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.

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

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(' ')

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 = ""

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

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

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

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


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 .


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.