#python #list #loops #iteration #nested-loops
#python #Список #циклы #итерация #вложенные циклы
Вопрос:
У меня есть два списка списков (a и b)
У них обоих всего 2 индекса на строку.
a
(50 000 строк) выглядит так:
|name|age|
|----|---|
|Dany|021|
|Alex|035|
Как список списков, выглядит так:
[['Dany', '021'],['Alex','035'], etc...]
b
(2000 строк) выглядит так:
|name|age|
|----|---|
|Paul| |
|Leon| |
Как список списков, выглядит так:
[['Paul', ''],['Leon',''], etc...]
Вопрос: Я хочу выполнить итерацию a
и b
в то же время — для каждой итерации a
, если a[0]
это in b[0]
, я хочу добавить соответствующий a[1]
into b[1]
.
Проще говоря, я хочу добавить возраст в свой b
список, просмотрев мой a
список, проверив, есть ли имя в a
списке, и если есть, взяв соответствующий возраст и добавив его в b
список для соответствующего имени.
Я пробовал вложенный цикл (повторяя через b и для каждой итерации, a
повторяя, чтобы проверить, существует ли какая-либо итерация a
at a[0]
в этой итерации b
at b[0]
), но после этого просто продолжаю теряться.
for row in b[1:]: # Excluding the headers
b_name = row[0]
b_age = row[1]
for row in a[1:]:
if b_name in row[0]:
b_age = row[1]
else:
b_age = ''
Проблема в том, что в итоге я получаю только одно значение b_age
, но должно быть 2000 уникальных b_age
значений?
Комментарии:
1. Это должны быть словари, а не списки списков. Или вы должны использовать
pandas
.2. Установка
b_age
значения не влияет на столбец списка, из которого оно получено.3. Вы ничего не добавляете, вы просто заменяете переменную. Вы имеете в виду, что хотите добавить их в виде чисел, объединить строки или составить список всех значений?
4. @Barmar как я должен использовать pandas в этом случае?
5. IMO, pandas — это огромный перебор для такого маленького проекта и с такими простыми требованиями.
Ответ №1:
Предполагая, что имена в a
уникальны, вы можете создать dict из a
, чтобы избежать повторения цикла снова и снова при замене пустых строковых значений b
. Например (добавил пару элементов в ваши примеры, чтобы проиллюстрировать, что произойдет, если имя в b
не существует в a
):
a = [['Dany', '021'], ['Alex','035'], ['Joe', '054']]
b = [['Alex',''], ['Dany', ''], ['Jane', '']]
d = {k: v for k, v in a}
b = [[k, d[k]] if k in d else [k, v] for k, v in b]
print(b)
# [['Alex', '035'], ['Dany', '021'], ['Jane', '']]
Если список, с которым вы на самом деле работаете, представляет собой простой список пар, как в примере, тогда вы можете заменить приведенное выше понимание dict на dict(a)
.
Кроме того, на случай, если это неясно, различные k, v
ссылки предназначены для удобства распаковки вложенных пар, но вы могли бы просто использовать одну переменную и получить доступ, используя индексные значения, такие как:
{x[0]: x[1] for x in a}
Комментарии:
1. Спасибо @benvc итак, если это не простой список пар, как мне это сделать?
2. @luca-martial — в зависимости от того, насколько сложны ваши вложенные списки, вы можете использовать модифицированную версию понимания dict в этом ответе. Если вложенные списки довольно сложные, было бы полезно, если бы вы опубликовали пример того, как они выглядят, чтобы мы могли лучше помочь.
Ответ №2:
Вы можете попытаться создать a
словарь, выполнив a_dict = dict(a)
это, что приведет к чему-то вроде этого:
{'Dany': '021', 'Alex': '035', etc...}
Тогда вы можете сделать что-то простое, например:
for person in b:
if person[0] in a_dict:
person[1] = a_dict[person[0]]
Это должно дать вам что-то вроде этого в b
:
[['Paul', ''], ['Leon', ''], ['Alex', '035'], etc...]
Ответ №3:
Если вы хотите обновить значения в b
, вам нужно выполнить цикл по индексу строки b. Перебор значений не будет работать, поскольку они не сохраняют свою связь с исходной строкой / столбцом b
.
Кроме того, предположительно, вы хотите назначить пустой возраст в качестве второго столбца b
только в том случае, если ни одно из имен a
не совпадает, а не только если текущее имя не совпадает.
Попробуйте это вместо:
for b_row_index in range(1, len(b)): # Excluding the headers
b_name = b[b_row_index][0]
for a_row in a[1:]:
if b_name in a_row[0]:
b[b_row_index][1] = a_row[1]
break
else:
b[b_row_index][1] = ''
Ответ №4:
Вы захотите указать возраст, чтобы вы могли выполнить серию быстрых поисков O (1) для каждой строки b
. Я бы начал с чего-то вроде:
# Make a dictionary of names to their ages
age = dict(a)
for row in b:
try:
# Set the age of this row to the age of row[0]
row[1] = age[row[0]]
except KeyError:
# End up here if row[0] is not in the "ages" dict
pass
Комментарии:
1. В какой части? Здесь все работает так, как ожидалось.
Ответ №5:
с помощью списков вы можете:
a = [['Dany', '021'],['Alex','035'], ['Paul', '060'],['Leon','070']]
b = [['Paul', ''],['Leon','']]
for i, b_item in enumerate(b):
for a_item in a:
if b_item[0]==a_item[0]:
b[i] = a_item
break
print(b)
вывод:
[['Paul', '060'], ['Leon', '070']]
Ответ №6:
Я думаю, как и многие другие упоминали; использование словарей здесь значительно упростило бы жизнь, вы можете конвертировать в словари, обрабатывать свои данные и добавлять возрасты, а затем конвертировать обратно в списки, если это то, что вам нужно. Этот код делает именно это:
a = [['Dany', '021'], ['Alex','035'], ['Joe', '054']]
b = [['Alex',''], ['Dany', ''], ['Jane', '']]
print(a)
print(b)
print(' ')
# convert to dict for simplicity
a_dictionary = dict(zip([e[0] for e in a], [e[1] for e in a]))
b_dictionary = dict(zip([e[0] for e in b], [e[1] for e in b]))
a_intersect_b = list(set(a_dictionary.keys()) amp; set(b_dictionary.keys()))
print(a_dictionary)
print(b_dictionary)
print(a_intersect_b)
print(' ')
# copy ages to b
for k in a_intersect_b:
b_dictionary[k] = a_dictionary[k]
print(a_dictionary)
print(b_dictionary)
print(' ')
# go back to lists
a = [[name, age] for name, age in zip(a_dictionary.keys(), a_dictionary.values())]
b = [[name, age] for name, age in zip(b_dictionary.keys(), b_dictionary.values())]
print(a)
print(b)
print(' ')
Вывод:
[['Dany', '021'], ['Alex', '035'], ['Joe', '054']]
[['Alex', ''], ['Dany', ''], ['Jane', '']]
{'Dany': '021', 'Alex': '035', 'Joe': '054'}
{'Alex': '', 'Dany': '', 'Jane': ''}
['Alex', 'Dany']
{'Dany': '021', 'Alex': '035', 'Joe': '054'}
{'Alex': '035', 'Dany': '021', 'Jane': ''}
[['Dany', '021'], ['Alex', '035'], ['Joe', '054']]
[['Alex', '035'], ['Dany', '021'], ['Jane', '']]