2013-08-06 7 views
132

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

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

Теперь, что я хочу сделать, это преобразовать каждый элемент в списке, чтобы плавать. Мое решение таково:

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

Но может ли это быть сделано с использованием вложенного списка, не так ли?

, что я сделал это:

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

Но тогда результат будет куча 100 с суммой 2400.

любое решение, объяснение было бы очень высокую оценку. Благодаря!

+12

Вы тоже * хотите сгладить свой список? –

+0

@GregHewgill: OP не ответил, но, основываясь на ответе, который они приняли, кажется, они хотели сохранить вложенность как есть. – smci

ответ

195

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

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

Это даст вам список списков, подобных тем, что вы начали с исключением с поплавками вместо строк. Если вам нужен один плоский список, вы должны использовать [float(y) for x in l for y in x].

36
>>> 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] 
2

Да, вы можете сделать это с таким кодом:

l = [[float(y) for y in x] for x in l] 
+0

'[float (y) для y в x для x в l]' это приведет к пучке из 100 с суммой 2400. –

3

Если вам не нравится вложенный списковые, вы можете использовать map функции, а также,

>>> from pprint import pprint 

>>> l = 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']] 

>>> pprint(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']] 

>>> float_l = [map(float, nested_list) for nested_list in l] 

>>> pprint(float_l) 
[[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]] 
+0

Ваш код генерирует объекты карты вместо списков: '>>> float_l = [ Карта (с плавающей точкой, nested_list) для nested_list в л] ' ' [[<карты в 0x47be9b0>], [<карта в 0x47be2e8>], [<карты в 0x47be4a8>], [<карта в 0x47beeb8>], [<карта в 0x484b048>], [<карты в 0x484b0b8>]] ' но добавление дополнительного вызова в список он работает, как ожидалось: ' >>> float_l = [список (карта (с плавающей точкой, nested_list)) для nested_list в l] ' – pixelperfect

+0

@pixelperfect, который обусловлен (* misinformed * ..) изменение в 'python3' для возврата генераторов из понятий. – javadba

0

Лучший способ сделать это, на мой взгляд, - использовать пакет itertools python.

>>>import itertools 
>>>l1 = [1,2,3] 
>>>l2 = [10,20,30] 
>>>[l*2 for l in itertools.chain(*[l1,l2])] 
[2, 4, 6, 20, 40, 60] 
16

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

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

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

+0

Это должен быть ответ, так как иногда мы не хотим, чтобы квадратная скобка была iteratool – zinking

+0

, это может быть неправильный ответ, поскольку он выводит не вложенный список, но это то, что я искал, особенно * принцип * , Благодаря! –

1

Эта проблема может быть решена без использования цикла. Для этого достаточно одного кода. Использование вложенной карты с функцией лямбда также будет работать здесь.

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

map(lambda x:map(lambda y:float(y),x),l) 

И выходной список будет следующим:

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

+1

У lambdas есть какие-либо преимущества в производительности, чем сказать @Andrew Clark или решения Гарри Бинсвангера (чем больше понимание ванильного списка)? Как лямбда кажется труднее читать. – Splatmistro

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

#Which can be written in single line as 
In [4]: [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[4]: [1.0] 
+0

Супер полезный! Делает это ясно, что петли (сверху вниз) упорядочены слева направо в генераторе. Это не очевидно, так как в (f (x) для x в l) "помещает вторую строку эквивалента for-loop слева. – user48956

+0

Большая полезная иллюстрация синтаксиса вложенных понятий (слегка неочевидного на первый взгляд). – wom

4

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

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

фактически такие же, как:

New_list=[] 
for x in l: 
    New_list.append(x) 

И теперь понимание вложенных списков:

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

такой же, как;

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

    new_list.append(sub_list) 

print(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]] 
2

У меня была аналогичная проблема, чтобы решить таким образом, я наткнулся на этот вопрос. Я сделал сравнение производительности ответа Эндрю Кларка и Нараяна, которые я хотел бы поделиться.

Основное различие между двумя ответами заключается в том, как они перебирают внутренние списки. Один из них использует встроенный map, в то время как другой использует понимание списка. Map function has slight performance advantage to its equivalent list comprehension if it doesn't require the use lambdas. Поэтому в контексте этого вопроса map должен выполнять несколько лучше, чем понимание списка.

Позволяет выполнить контрольный показатель производительности, чтобы убедиться, что это действительно так. Я использовал python версии 3.5.0 для выполнения всех этих тестов. В первом наборе тестов я хотел бы сохранить элементы в список, чтобы и варьировать количество списков от 10-100,000

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10]" 
>>> 100000 loops, best of 3: 15.2 usec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10]" 
>>> 10000 loops, best of 3: 19.6 usec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100]" 
>>> 100000 loops, best of 3: 15.2 usec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100]" 
>>> 10000 loops, best of 3: 19.6 usec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*1000]" 
>>> 1000 loops, best of 3: 1.43 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*1000]" 
>>> 100 loops, best of 3: 1.91 msec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10000]" 
>>> 100 loops, best of 3: 13.6 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10000]" 
>>> 10 loops, best of 3: 19.1 msec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100000]" 
>>> 10 loops, best of 3: 164 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100000]" 
>>> 10 loops, best of 3: 216 msec per loop 

enter image description here

В следующем наборе тестов я хотел бы для увеличения количества элементов в списках до .

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10]" 
>>> 10000 loops, best of 3: 110 usec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10]" 
>>> 10000 loops, best of 3: 151 usec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100]" 
>>> 1000 loops, best of 3: 1.11 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100]" 
>>> 1000 loops, best of 3: 1.5 msec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*1000]" 
>>> 100 loops, best of 3: 11.2 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*1000]" 
>>> 100 loops, best of 3: 16.7 msec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10000]" 
>>> 10 loops, best of 3: 134 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10000]" 
>>> 10 loops, best of 3: 171 msec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100000]" 
>>> 10 loops, best of 3: 1.32 sec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100000]" 
>>> 10 loops, best of 3: 1.7 sec per loop 

enter image description here

Давайте смелый шаг и изменить количество элементов в списке, чтобы быть

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10]" 
>>> 1000 loops, best of 3: 800 usec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10]" 
>>> 1000 loops, best of 3: 1.16 msec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100]" 
>>> 100 loops, best of 3: 8.26 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100]" 
>>> 100 loops, best of 3: 11.7 msec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*1000]" 
>>> 10 loops, best of 3: 83.8 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*1000]" 
>>> 10 loops, best of 3: 118 msec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10000]" 
>>> 10 loops, best of 3: 868 msec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10000]" 
>>> 10 loops, best of 3: 1.23 sec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100000]" 
>>> 10 loops, best of 3: 9.2 sec per loop 
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100000]" 
>>> 10 loops, best of 3: 12.7 sec per loop 

enter image description here

Из этих испытаний можно сделать вывод, что map в этом случае имеет преимущество по сравнению со списком. Это также применимо, если вы пытаетесь использовать либо int, либо str. Для небольшого количества списков с меньшим количеством элементов в списке разница незначительна. Для более крупных списков с большим количеством элементов в списке вы можете использовать map вместо понимания списка, но это полностью зависит от потребностей приложения.

Однако я лично считаю, что понимание списка является более читаемым и идиоматичным, чем map. Это стандарт де-факто в python. Обычно люди более опытные и удобные (особенно новичок) в использовании понимания списка, чем map.