Используя Python, у меня есть несколько списков, к которым я хочу присоединить текст. Эти списки имеют многоуровневые записи (или любой другой термин, который используется для его описания), например:

list1:
   (['abc'],
    ['def', 'ghi'])
list2:
   (['123'],
    ['456', '789'])

Я хотел бы присоединить строку «X» к каждому элементу обоих списков:

list1:
   (['Xabc'],
    ['Xdef', 'Xghi'])
list2:
   (['X123'],
    ['X456', 'X789'])

Я просто не могу сделать это аккуратно . Я сделал несколько «для циклов», но это кажется невероятно плохим и не воспроизводимым, учитывая, что у меня есть несколько списков:

for index, item in enumerate(list1):
    for index2, item2 in enumerate(item):
        list1[index][index2] = "X" + item2

for index, item in enumerate(list2):
    for index2, item2 in enumerate(item):
        list2[index][index2] = "X" + item2

Я знаю, что это должен быть один лайнер. Я нашел несколько ответов для отдельных простых списков, но те, которые у меня есть, содержат многоуровневые (многоэлементные?) Списки:

list = ["X" + string for string in list]

Я просто не могу это адаптировать. Есть предположения? Заранее спасибо.

1
spcvalente 3 Июл 2019 в 15:41

3 ответа

Лучший ответ

Возможно, вам будет интересно узнать о назначении срезов, если вас интересовали все индексы, которые вы создавали с помощью перечисления, а что нет.

for b in list1 :
    b[:]= ["X"+a for a in b]

Хотя технически это не делает назначение на месте (оно создает список для понимания списка), оно будет эффективно обновлять list1 напрямую, и не требует, чтобы вы затем присваивали list1 = [список понимания]

Если вы хотите на самом деле предоставить отдельные параметры, вы бы использовали звездочку для упаковки переменных в список.

def update_lists(prepend_text, *lists) :
    for list in lists :
        update_list(prepend_text, list)

def update_list(prepend_text, list) :
    for b in list :
        b[:]= [prepend_text+a for a in b] 
update_lists("X", list1,list2)

В качестве альтернативы вы можете определить функцию следующим образом:

def update_lists(prepend_text, lists) :
    for list in lists :
        update_list(prepend_text, list)

А затем вызвать функцию как

update_lists("X", [list1,list2])

Или, может быть, лучше, если вы создаете список списков динамически

lists = []
lists.append(list1)
lists.append(list2)
update_lists("X", lists)
1
FredMan 3 Июл 2019 в 13:47

Вам нужно понимание вложенного списка, чтобы сохранить структуру в результирующем списке:

list1 = [['abc'], ['def', 'ghi']]

[[f'X{j}' for j in i] for i in list1]
# [['X{}'.format(j) for j in i] for i in list1] # for python 3.6 <
[['Xabc'], ['Xdef', 'Xghi']]

Для нескольких списков вы можете определить следующую функцию генератора:

def add_text(text, *lists): 
    for l in lists:
        yield [[text + '{}'.format(j) for j in i] for i in l] 

l1, l2 = list(add_text('X', list1, list2))

print(l1)
# [['Xabc'], ['Xdef', 'Xghi']]

print(l2)
# [['XX123'], ['XX456', 'XX789']]
2
yatu 3 Июл 2019 в 13:18

Рекурсивный подход для вложенных списков:

list1=[['abc'], [ ['def', 'ghi'],'jlk']]


def apply(f,nested) :
    if isinstance(nested,str): return f(nested)
    return [ apply(f,x) for x in nested ]

apply(lambda s : "X"+s , list1 )
Out : [['Xabc'], [['Xdef', 'Xghi'], 'Xjlk']] 
1
B. M. 3 Июл 2019 в 13:17