リストの要素のペアを結合する


82

次のように、リストを結合して1つの長い文字列を作成できることを知っています。

x = ['a', 'b', 'c', 'd']
print ''.join(x)

明らかに、これは次のように出力されます。

'abcd'

しかし、私がやろうとしているのは、リストの最初と2番目の文字列を結合してから、3番目と4番目というように結合することです。要するに、上記の例から、代わりに次の出力を達成します。

['ab', 'cd']

これを行う簡単な方法はありますか?文字列の数は常に偶数ですが、リスト内の文字列の長さやリスト内の文字列の数は予測できないことにも言及する必要があります。したがって、元のリストは次のようになります。

['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'] 

「リスト内の文字列の長さは予測できないことにも言及する必要があります」 –では、長さは重要ですか?つまり、リスト要素のすべてのペアを結合したいだけですか、それとも実際にコンテンツを見て、結果の要素が特別な長さの制限を下回っている限り結合したいですか?
突く

単にすべてのペアに参加します。ペアの数がわからないことが問題になる可能性があると思いました
John

回答:


75

次の手順でスライス表記を使用できます。

>>> x = "abcdefghijklm"
>>> x[0::2] #0. 2. 4...
'acegikm'
>>> x[1::2] #1. 3. 5 ..
'bdfhjl'
>>> [i+j for i,j in zip(x[::2], x[1::2])] # zip makes (0,1),(2,3) ...
['ab', 'cd', 'ef', 'gh', 'ij', 'kl']

同じロジックがリストにも適用されます。2つの文字列を単純に追加するだけなので、文字列の長さは重要ではありません。


1
kevpieの答えがはるかに優れていることは間違いありません。これでx[:::2]は、オブジェクトをx[1::2]作成し、別のオブジェクトを作成します。これらの作成は、おそらく内部のインデックスの計算に基づいており、要素の連続するペアを取得するには、これら2つのオブジェクトを引数として渡した関数を呼び出す必要があります。それは連結する必要があります。kevpieの答えでは、イテレータを1つ作成するだけで、インデックスを処理することなく、変更されていないリストの要素から要素へと反復がスキップされます。これは、はるかにPython的です。
eyquem 2014

@eyquemは、itertools.islice[]の代わりに使用して、中間オブジェクトを削除します。しかし、両方の答えは同じ条件で機能し、同じように返されるので、両方とも正しいです。そしてzip(i[::2], i[1::2])、私にはとても甘く見えるので、なぜですか?:)
utdemir 2014年

これはシーケンスでのみ機能しますが、@ kevpieの答えはより一般的で、反復可能なもので機能します。
コス

37

イテレータを使用します。

リスト内包表記:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> [c+next(si, '') for c in si]
['abcde', 'fghijklmn', 'opqr']
  • メモリ使用量に非常に効率的です。
  • sの正確に1つのトラバース

ジェネレータ式:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> pair_iter = (c+next(si, '') for c in si)
>>> pair_iter # can be used in a for loop
<generator object at 0x4ccaa8>
>>> list(pair_iter) 
['abcde', 'fghijklmn', 'opqr']
  • イテレータとして使用

マップを使用して、str .__ add __、iter

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> map(str.__add__, si, si)
['abcde', 'fghijklmn', 'opqr']

next(iterator [、default])はPython2.6以降で利用可能です


2
断然、ベストアンサー。utdemirの答えに対する私のコメントを参照してください。
eyquem 2014

4

ただpythonicであるために:-)

>>> x = ['a1sd','23df','aaa','ccc','rrrr', 'ssss', 'e', '']
>>> [x[i] + x[i+1] for i in range(0,len(x),2)]
['a1sd23df', 'aaaccc', 'rrrrssss', 'e']

リストの長さが奇数の場合に警告したい場合は、次のことを試してください。

[x[i] + x[i+1] if not len(x) %2 else 'odd index' for i in range(0,len(x),2)]

幸運を祈ります


2

一時的なリストを作成せずに:

>>> import itertools
>>> s = 'abcdefgh'
>>> si = iter(s)
>>> [''.join(each) for each in itertools.izip(si, si)]
['ab', 'cd', 'ef', 'gh']

または:

>>> import itertools
>>> s = 'abcdefgh'
>>> si = iter(s)
>>> map(''.join, itertools.izip(si, si))
['ab', 'cd', 'ef', 'gh']

いいですが、私のコードを考えると、とにかく元のリストから始めてしまうので、utdmrを選ぶのは悪いと思います....ありがとうございます
John


1

私はRegsが苦手なので、このようにします。

コード

t = '1. eat, food\n\
7am\n\
2. brush, teeth\n\
8am\n\
3. crack, eggs\n\
1pm'.splitlines()

print [i+j for i,j in zip(t[::2],t[1::2])]

出力:

['1. eat, food   7am', '2. brush, teeth   8am', '3. crack, eggs   1pm']  

お役に立てれば :)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.