Menggabungkan elemen daftar jika elemen-elemen itu berada di antara dua spasi putih

24

Saya punya input seperti ini:

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

Saya ingin bergabung antara elemen ''untuk memiliki output seperti ini:

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

Saya mencoba menggunakan join dan mendaftar slicing seperti ini:

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

Ini berfungsi sampai batas tertentu tetapi saya tidak tahu bagaimana cara mengulangi instruksi ini untuk seluruh daftar.

mewtire
sumber

Jawaban:

27

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

Keluaran:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']
Chris
sumber
2
Penjelasan: Ini menggunakan "bool" untuk memeriksa nilai "Falsey", seperti string kosong atau Tidak ada.
noɥʇʎԀʎzɐɹƆ
7

Ini mengerikan dan berantakan, tetapi

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

dapat mengambil string apa pun yang Anda dapat menjamin tidak terkandung dalam daftar, dan mengembalikan fungsi melakukan apa yang Anda inginkan. Tentu saja, Anda mungkin ingin hanya menggunakan ini sekali atau dua kali untuk situasi spesifik Anda, jadi, jika Anda dapat menjamin bahwa tidak ada elemen daftar yang berisi spasi, ini mungkin terlihat seperti:

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

Jika Anda tidak dapat atau tidak ingin menggunakan itertools:

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 = ""
Asad
sumber
3

Kamu bisa melakukan ini:

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

Keluaran:

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

Edit setelah komentar:

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

Keluaran:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']
naif
sumber
# get the indices.bukan komentar yang sangat berguna. Saya sarankan Anda membuatnya berguna (misalnya filter the indices to keep only those that correspond to whitespace), atau menghapusnya sama sekali.
Alexander - Pasang kembali Monica
Juga, tidak bisakah proses 2 langkah itu disederhanakan indices = [i for s in a if s == '']?
Alexander - Pasang kembali Monica
@Alexander Saya pikir saran Anda untuk baris 2 akan menjadi kesalahan sintaks. Baris 2 dapat dihapus jika Anda cukup menambahkan tanda centang "sama dengan string nol" ke baris tiga sepertiindx = [i for i, x in enumerate(a) if x == '']
Reimus Klinsman
Sayangnya, jawaban ini tidak menjelaskan bahwa elemen pertama atau terakhir adalah sesuatu yang harus digabungkan. seperti a = ['asse','mbly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c+', '+']tetapi sepertinya Anda dapat meningkatkan baris 3 Anda dengan menambahkan daftar dengan string nol di ujung enumerate([''] + a + [''])kemudian menghapus a[0:indx[0]]dan a[indx[-1]+1:]pada baris Anda 4. Ini masih tidak menjelaskan apakah ada dua string nol tepat di sebelah satu sama lain meskipun
Reimus Klinsman
1
Terima kasih @KeiNagase untuk komentar yang bagus. Lihat hasil edit.
naif
2

Jika pembatas input sebenarnya adalah string kosong, maka Anda dapat melakukannya

strlist = [x or ' ' for x in a]
joined = ''.join(strlist).split()
joined
['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']
realgeek
sumber
Maaf, tidak melihat jawaban Unrelated String. Jika Anda membagi () tanpa parameter, itu akan menutup semua spasi putih, yang sedikit lebih kuat.
realgeek
1

Cukup tua tetapi masih bermanfaat:

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)

Ini menghasilkan

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']
Jan
sumber
1

menjalankan loop di atas daftar
di dalam loop menambahkan elemen ke string kosong sementara dan memeriksa kondisi apakah elemen tersebut adalah string kosong atau elemen terakhir dari daftar, jika benar maka tambahkan variabel sementara ke daftar output dan ubah nilainya. variabel itu ke Kode string kosong
:

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)

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

Eswar
sumber
1

Saya setuju bahwa jawaban Cris menggunakan pendekatan python yang paling , tetapi akan lebih baik untuk mengadaptasi jawaban Cris sedikit. Alih-alih menggunakan groupby(l,key = bool)untuk menggunakan groupby(l, key = lambda x: x !='')dan menyingkirkan ambiguitas yang tidak perlu

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]

Seperti yang dinyatakan dalam The Zen of Python : Eksplisit lebih baik daripada implisit

NB Saya hanya menulis jawaban baru karena saya tidak memiliki reputasi yang cukup untuk menulis komentar tentang jawaban Cris .

N.Nonkovic
sumber
1

Versi lain yang berfungsi, dengan hanya loop / tes dasar:

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
B. Pergi
sumber