Вопрос-Ответ

How can I use list comprehensions to process a nested list?

Как я могу использовать list comprehensions для обработки вложенного списка?

У меня есть этот вложенный список:

l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]

Я хочу преобразовать каждый элемент из l в float. У меня есть этот код:

newList = []
for x in l:
for y in x:
newList.append(float(y))

Как я могу решить проблему с пониманием вложенного списка вместо этого?


Смотрите также: Как я могу получить плоский результат из понимания списка вместо вложенного списка?

Переведено автоматически
Ответ 1

Вот как вы могли бы сделать это с пониманием вложенного списка:

[[float(y) for y in x] for x in l]

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

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

[float(y) for x in l for y in x]

Обратите внимание на порядок выполнения цикла - for x in l здесь на первом месте.

Ответ 2

Вот как преобразовать вложенный цикл for в понимание вложенного списка: введите описание изображения здесь

Вот как работает понимание вложенного списка:

            l a b c d e f
↓ ↓ ↓ ↓ ↓ ↓ ↓
In [1]: l = [ [ [ [ [ [ 1 ] ] ] ] ] ]
In [2]: for a in l:
...: for b in a:
...: for c in b:
...: for d in c:
...: for e in d:
...: for f in e:
...: print(float(f))
...:
1.0

In [3]: [float(f)
for a in l
...: for b in a
...: for c in b
...: for d in c
...: for e in d
...: for f in e]
Out[3]: [1.0]

В вашем случае, если вам нужен плоский список, это будет что-то вроде этого.

In [4]: new_list = [float(y) for x in l for y in x]

Еще один интересный пример с условиями if в сочетании:

In [5]: school_data = [
...: {
...: "students": [
...: {"name": "John", "age": 18, "friends": ["Alice", "Bob"]},
...: {"name": "Alice", "age": 19, "friends": ["John", "Bob"]},
...: ],
...: "teacher": "Mr. Smith",
...: },
...: {
...: "students": [
...: {"name": "Sponge", "age": 20, "friends": ["Bob"]},
...: ],
...: "teacher": "Mr. tom",
...: },
...: ]

In [6]: result = []

In [7]: for class_dict in school_data:
...: for student_dict in class_dict["students"]:
...: if student_dict["name"] == "John" and student_dict["age"] == 18:
...: for friend_name in student_dict["friends"]:
...: if friend_name.startswith("A"):
...: result.append(friend_name)

In [8]: result
Out[8]: ['Alice']

И вот listcomp версия

In [9]: [
...: friend_name
...: for class_dict in school_data
...: if class_dict["teacher"] == "Mr. Smith"
...: for student_dict in class_dict["students"]
...: if student_dict["name"] == "John" and student_dict["age"] == 18
...: for friend_name in student_dict["friends"]
...: if friend_name.startswith("A")
...: ]
Out[9]: ['Alice']
Ответ 3

Не уверен, какой ваш желаемый результат, но если вы используете понимание списка, порядок соответствует порядку вложенных циклов, который у вас задом наперед. Итак, я получил то, что, как я думаю, вы хотите, с помощью:

[float(y) for x in l for y in x]

Принцип таков: используйте тот же порядок, который вы использовали бы при написании вложенных циклов for .

Ответ 4
>>> l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
>>> new_list = [float(x) for xs in l for x in xs]
>>> new_list
[40.0, 20.0, 10.0, 30.0, 20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0, 30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]
python list