Bu öğeler iki boşluk arasındaysa listenin öğelerini birleştirme


24

Ben böyle bir girdi var:

['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

Ben ''böyle bir çıktı için öğeleri birleştirmek istiyorum:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

Kullanmayı denedim joinve dilimlemeyi şöyle listeledim:

a=['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
a[2:5] = [''.join(a[ 2: 5])]
a=['assembly', '', 'python', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

Bu bir dereceye kadar işe yarıyor ama bu talimatın tamamını liste için nasıl tekrarlayacağımı bilmiyorum.

Yanıtlar:


27

Kullanma itertools.groupby:

from itertools import groupby

l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
new_l = [''.join(g) for k, g in groupby(l, key = bool) if k]

Çıktı:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

2
Açıklama: Boş bir dize veya Yok gibi bir "Falsey" değerini denetlemek için "bool" kullanır.
noɥʇʎԀʎzɐɹƆ

7

Bu korkunç ve hileli, ama

lambda b:lambda l:''.join(i or b for i in l).split(b)

listenin birleşiminde bulunmadığını garanti edebileceğiniz herhangi bir dize alabilir ve istediğinizi yapan bir işlev döndürür. Elbette, bunu özel durumunuz için sadece bir veya iki kez kullanmak istersiniz, bu nedenle, listenin hiçbir öğesinin boşluk içermediğini garanti ederseniz, daha fazla gibi görünebilir:

a = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
a = ''.join(i or ' ' for i in a).split(' ')

4

Itertools'u kullanamıyorsanız veya kullanmak istemiyorsanız:

l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
l_new = []
combined = ""
for idx, s in enumerate(l):
    if s != "":
        combined += s
        if idx == len(l)-1:
            l_new.append(combined)

    else:
        l_new.append(combined)
        combined = ""

3

Bunu yapabilirsiniz:

a = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
indx = ['' == k for k in a]
indx = [i for i, x in enumerate(indx) if x] # get the indices.
a_merged = a[0:indx[0]] + [''.join(a[indx[i]:indx[i+1]]) for i in range(len(indx)) if i < len(indx)-1] + a[indx[-1]+1:] # merge the list

Çıktı:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

Yorumlardan sonra düzenle:

a = ['assembly', '','',  'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
indx = [i for i, x in enumerate(a) if x == ''] # get the indices where '' occurs in the original list. 
a_merged = a[0:indx[0]] + [''.join(a[indx[i]:indx[i+1]]) for i in range(len(indx)) if i < len(indx)-1 and indx[i+1] -indx[i] > 1] + a[indx[-1]+1:]
a_merged

Çıktı:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

# get the indices.çok yararlı bir yorum değil. Bunu yararlı hale getirmenizi (örn. filter the indices to keep only those that correspond to whitespace) Veya tamamen kaldırmanızı öneririm .
Alexander - Monica'yı eski

Ayrıca, bu 2 adımlı işlem basitleştirilemez indices = [i for s in a if s == '']mi?
Alexander - Monica'yı eski

@Alexander Satır 2 için önerinizin sözdizimi hatası olacağını düşünüyorum. Satır 2, üç satırına "null dizeye eşittir" indx = [i for i, x in enumerate(a) if x == '']
onayını eklerseniz kaldırılabilir

Ne yazık ki, bu cevap ilk veya son öğenin birleştirilmesi gereken bir şey olduğunu açıklamaz. gibi a = ['asse','mbly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c+', '+']ama sizi ucundaki boş dize içeren bir liste ekleyerek Çizginizi 3 artırabilirsiniz gibi görünen bir enumerate([''] + a + [''])sonra kaldırma a[0:indx[0]]ve a[indx[-1]+1:]hemen yanındaki birbirinden için iki boş dizeleri varsa hattınıza 4. Bu hala dikkate almaz gerçi
Reimus Klinsman

1
İyi yorumlar için @KeiNagase'e teşekkürler. Düzenlemeye bakın.
saf

2

Giriş sınırlayıcılar aslında boş dizeler ise,

strlist = [x or ' ' for x in a]
joined = ''.join(strlist).split()
joined
['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

Üzgünüz, İlgisiz Dize'nin cevabını görmedim. Parametre olmadan split () yaparsanız, biraz daha sağlam olan tüm boşlukları daraltır.
realgeek

1

Oldukça eski ama yine de kullanışlı:

from itertools import groupby

lst = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

new_lst = [''.join(values)
           for key, values in groupby(lst, key = lambda x: x == '')
           if not key]
print(new_lst)

Bu,

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

1

döngü
içindeki liste üzerinde bir döngü çalıştırın , öğeyi geçici bir boş dizeye ekleyin ve öğenin boş bir dize mi yoksa listenin son öğesi mi olduğunu kontrol edin, true ise, geçici değişkeni çıkış listesine ekleyin ve değeri değiştirin bu değişkenin boş bir dize ile
kodlanması:

x=['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
temp=''
output=[]
for y in x:
    temp=temp+y
    if y=='' or y==x[-1]:
        output.append(temp)
        temp=''

print(output)

Çıktı: ['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']


1

Cris cevabının çoğu python yaklaşımını kullandığını kabul ediyorum , ancak Cris cevabını biraz uyarlamak iyi olacak . Gereksiz belirsizliğigroupby(l,key = bool) kullanmak groupby(l, key = lambda x: x !='')ve kurtulmak için kullanmak yerine

from itertools import groupby

separator = ''
l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
new_l = [''.join(g) for k, g in groupby(l, key = lambda x: x !=separator) if k]

Python'un Zen'inde belirtildiği gibi : Açık, örtük olmaktan iyidir

Not : Sadece yeni cevabı yazıyorum çünkü Cris cevabı hakkında yorum yazmak için yeterli itibarım yok .


1

Yalnızca temel döngüler / testlerle başka bir çalışma sürümü:

txt = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

out = []
temp = ''

for s in txt:
   if s == '':
      if temp != '':
         out.append(temp) 
         temp = ''
      out.append('')
   else:
      temp = temp + s

if temp != '':
   out.append(temp)

out
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.