2012-07-14 82 views
0

我想根據它們是否以相同的元素開始,在文件中連接兩行。
我可以將每行的第一個元素變成一個列表,並使用這個列表中的元素來搜索每一行,但這似乎不是最有效的方式?Python:連接包含特定字符串的行

我有以下文件

1,AF534061.1,T,A 
1,K02718.1,T,A 
16,AF534061.1,G,- 
16,K02718.1,G,- 
17,AF534061.1,T,- 
17,K02718.1,T,- 
18,AF534061.1,A,- 
18,K02718.1,A,- 
19,AF534061.1,T,- 
19,K02718.1,T,- 
20,AF534061.1,A,- 
20,K02718.1,A,- 
21,AF534061.1,A,- 
21,K02718.1,A,- 
24,AF534061.1,C,T 

我想,如果第一項是線之間共享聯接線。所以,我想獲得以下輸出

1,AF534061.1,T,A,1,K02718.1,T,A 
16,AF534061.1,G,-,16,K02718.1,G,- 
17,AF534061.1,T,-,17,K02718.1,T,- 
18,AF534061.1,A,-,18,K02718.1,A,- 
19,AF534061.1,T,-,19,K02718.1,T,- 
20,AF534061.1,A,-,20,K02718.1,A,- 
21,AF534061.1,A,-,21,K02718.1,A,- 
24,AF534061.1,C,T 

在這個例子中,它看起來像我只是也許能加入每隔一個線,但我希望(需要)使代碼更一般!

我不認爲這很難,但我似乎無法弄清楚! 感謝您的幫助

+0

請參閱此處以瞭解[在StackOverflow上提出問題的正確方法](http://meta.stackexchange.com/a/130667/186178)。 – 2012-07-14 02:09:41

+1

這看起來是csv可讀的。你應該可以使用python的'csv'模塊來輕鬆解析這個。 – 2012-07-14 02:15:16

回答

5

Python標準庫已滿的工具。對於這份工作,請使用itertools.groupby

import itertools 

lines = '''1,AF534061.1,T,A 
1,K02718.1,T,A 
16,AF534061.1,G,- 
16,K02718.1,G,- 
17,AF534061.1,T,- 
17,K02718.1,T,- 
18,AF534061.1,A,- 
18,K02718.1,A,- 
19,AF534061.1,T,- 
19,K02718.1,T,- 
20,AF534061.1,A,- 
20,K02718.1,A,- 
21,AF534061.1,A,- 
21,K02718.1,A,- 
24,AF534061.1,C,T'''.split('\n') 

for key, group in itertools.groupby(lines, lambda line: line.partition(',')[0]): 
    print ','.join(group) 
+1

你可以使用'groupby(csv_reader,key = itemgetter(0))'和'csv_writer.writerow(chain。from_terable(group))' – jfs 2012-07-14 02:23:40

+0

@ J.F.Sebastian聽起來像你應該提交一個解決方案或將其添加到這裏。 – jamylak 2012-07-14 06:25:55

0

您可以使用正則表達式和反向引用。

print re.sub(r'(([^,]+).*)\n(\2.*\n)', r'\1\3', data) 

這裏的表現解釋說:

(   # Start of first line 
(   # Start of first part of line, refered to as \2 
    [^,]+  # Everything before the first comma 
) 
.*   # Remainder of first line 
)    # This new line isn't in any capture groups, so it'll be 
\n   # removed from any matched results 
(   # Start of second line 
    \2   # This takes the first part of the first line and requires 
       # it to match again 
    .*   # Remainder of second line 
    \n   # We include this newline to make the next search start at 
       # the start of the following line. It's reinserted because 
       # it's in the second line's capture group. 
) 
+1

誰可以投下來解釋一下嗎?我想提高我的答案。謝謝。 – FakeRainBrigand 2012-07-14 02:18:10

+0

我沒有低估這個,還沒有測試它是否有效,但我猜測它被低估是因爲人們討厭它時,你認爲的第一件事是用正則表達式解決所有問題。它導致代碼非常不明確,雖然它對知識有好處,所以如果它工作,我肯定不會投票。與'groupby'解決方案相比,它看起來非常醜陋:D – jamylak 2012-07-14 06:22:15

+0

@jamylak基於對正則表達式的傾向進行的downvoting與投票答案的目的相反。正則表達式比groupby方法更加清晰或者不太明確是主觀的,也不會值得讚揚。 – 2012-08-15 21:12:25

-2

我沒有測試此代碼,但這樣的事情應該工作:

common = {} 
for line in file.readLines(): 
    prefix = line.split(",")[0] 
    if prefix in common: 
    common[prefix].append(line) 
    else: 
    common[prefix] = [line] 

for key, values in common: 
    print values.join(",") 
+1

然而,如果我低估了,我做錯了什麼,我該如何改進我的答案? – matzahboy 2012-07-14 02:36:25

+1

-1詞典沒有順序,所以行可能會或可能不會以正確的順序輸出。不需要在文件上調用'readlines()',你可以像下面這樣迭代:'f'中的行(使用'file'作爲名字是壞的,因爲它會影響內置的)。而不是檢查字典中的鍵,你可以使用'common.setdefault(prefix,[])。append(line)'。 此外,由於字典默認迭代鍵,所以最後一部分'for key,values common:',甚至不起作用。需要爲'key','common.items'中的值'' – jamylak 2012-07-14 06:31:21

相關問題