Bir listenin öğe çiftlerini birleştirme


82

Aşağıdaki gibi bir uzun dizge oluşturmak için bir listenin birleştirilebileceğini biliyorum:

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

Açıkçası bu çıktı:

'abcd'

Ancak, yapmaya çalıştığım şey basitçe listedeki birinci ve ikinci dizeleri birleştirmek, ardından üçüncü ve dördüncü dizileri birleştirmek vb. Kısaca, yukarıdaki örnekten bunun yerine şu çıktıyı elde edin:

['ab', 'cd']

Bunu yapmanın basit bir yolu var mı? Listedeki dizgelerin uzunluklarının ve listedeki dizelerin sayısı her zaman çift olmasına rağmen tahmin edilemez olacağını muhtemelen belirtmeliyim. Yani orijinal liste şu şekilde olabilir:

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

"Listedeki dizelerin uzunluklarının tahmin edilemez olacağını da belirtmeliyim" - Öyleyse uzunluk önemli mi? Yani sadece her liste öğesi çiftine katılmak mı istiyorsunuz, yoksa gerçekten içeriğe bakmak ve ortaya çıkan öğe belirli bir uzunluk sınırının altında kaldığı sürece katılmak mı istiyorsunuz?
dürtmek

sadece her çifte katılın, sadece çiftlerin sayısını bilmemenin bir sorun olabileceğini düşündüm
John

Yanıtlar:


76

Dilim gösterimini aşağıdaki adımlarla kullanabilirsiniz:

>>> 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']

Aynı mantık listeler için de geçerlidir. Dize uzunluğu önemli değil, çünkü sadece iki dizgeyi ekliyorsunuz.


1
Hiç şüphe yok ki kevpie'nin cevabı çok daha iyi. Bu bir, x[:::2]bir amacı oluşturur, x[1::2]başka bir amacı oluşturur, bu tasarımlar muhtemelen başlık altında indekslerin hesaplamaya dayalı ve bağımsız değişkenler olarak geçirilen, bu iki nesne ile bir işlev arama öğelerinin peş peşe çiftleri elde için önce gerekli olan edilen sıralanmalıdır. Kevpie'nin cevabında, sadece bir yineleyicinin oluşturulması var ve sonra yineleme, dizinlerle ilgilenmek zorunda kalmadan el değmemiş listenin öğesinden öğesine atlıyor ve bu çok daha fazla pitonik.
eyquem

@eyquem, itertools.islice[] yerine kullanmak , ara nesneleri ortadan kaldırır. Ancak her iki yanıt da aynı koşullarda çalıştığı ve aynı sonucu verdiği için ikisi de haklıdır. Ve zip(i[::2], i[1::2])bana çok tatlı görünüyor, neden olmasın? :)
utdemir

@ Kevpie'nin yanıtı daha genel ve yinelenebilir herhangi bir şey üzerinde çalışırken, bu yalnızca diziler üzerinde çalışır .
Kos

37

Bir yineleyici kullanın.

Listeyi anlama:

>>> si = iter(['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'])
>>> [c+next(si, '') for c in si]
['abcde', 'fghijklmn', 'opqr']
  • Bellek kullanımı için çok verimli.
  • S tam olarak bir geçiş

Jeneratör ifadesi:

>>> 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']
  • yineleyici olarak kullan

Map, str .__ add__, iter kullanarak

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

sonraki (yineleyici [, varsayılan]) Python 2.6'dan itibaren kullanılabilir


2
Açık ara en iyi cevap. Utdemir'in cevabına yorumumu görün.
eyquem

4

sadece pitonik :-)

>>> 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']

eğer alarm almak istemeniz durumunda, liste uzunluğu tuhafsa deneyebilirsiniz:

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

İyi şanslar


2

Geçici listeler oluşturmadan:

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

veya:

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

Güzel, ama benim kodumun yine de orijinal listeyle başlamama neden olduğunu düşünürsek, sanırım utdmr'leri tercih etmeyeceğim .... yine de teşekkürler
John

1
>>> lst =  ['abcd', 'e', 'fg', 'hijklmn', 'opq', 'r'] 
>>> print [lst[2*i]+lst[2*i+1] for i in range(len(lst)/2)]
['abcde', 'fghijklmn', 'opqr']

1

Regs ile iyi olmadığım için bu şekilde yapardım ..

KOD

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])]

çıktı:

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

Bu yardımcı olur umarım :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.