Изравнете вътрешния списък, без да променяте външния списък в python

И така, просто въвеждането на python flatten list в stack-overflow/google връща огромен брой дублиращи се резултати. Опитах всички от тях и никой не е приложим в този конкретен случай.

Получавам обратно набор от резултати от база данни от pyodbc, което ми дава структура от данни, която мога да принудя към списък със списъци. Първият елемент (първата колона) във всеки върнат ред е във формата "a.b.c". Бих искал да е "a", "b", "c". Първият ми инстинкт беше да се разделя на период, което и направих.

Преди:

[["a.b.c", "d", 1], ["e.f.g", "h", 2], ... ] # rows left out for brevity

След:

# unfortunately, split returns a list, which then gets nested
[[["a", "b", "c"], "d", 1], [["e", "f", "g"], "h", 2], ... ]

Но това, което бих искал да видя е:

[["a", "b", "c", "d", 1], ["e", "f", "g", "h", 2], ... ]

Опитах предишните решения за препълване на стека за изравняване на списък, но докато всички споменават вложени списъци, никой не казва как да изравним само вложените списъци.

Опитах:

from itertools import chain
for row in rows:
    row = list(chain(row)) # python won't allow modifications in a loop

и

rows = [list(chain(row)) for row in rows]

Предполагам, че трябва да има начин, може би с добив, да се направи нещо като:

for row in rows:
    row = row[0].append(row[1:]) # but this doesn't work either

Не знам как да променя вътрешните списъци в списък със списъци. Ако има по-добър начин от този, който съм опитвал досега, ще се радвам да го чуя. Благодаря ви предварително за помощта.


person Caleb    schedule 20.04.2013    source източник
comment
python няма да позволи модификации в цикъл - Това не ви пречи да получите това, което желаете в тази ситуация... като правите това, вие просто обвързвате името row с нова стойност, това е < i>разрешено, но не постига нищо...   -  person jamylak    schedule 21.04.2013


Отговори (1)


Какво ще кажеш:

>>> s = [["a.b.c", "d", 1], ["e.f.g", "h", 2]]
>>> [k[0].split('.') + k[1:] for k in s]
[['a', 'b', 'c', 'd', 1], ['e', 'f', 'g', 'h', 2]]

Това взема списъка, който split връща след действие върху първия елемент, и го добавя към списък, състоящ се от останалите.

person DSM    schedule 20.04.2013
comment
+1, няма причина да го правите вложен, след това да го изравнявате, по-лесно е просто да го направите с един замах. Имайте предвид, че в 3.x можете да направите [k.split('.') + rest for k, *rest in s] за по-лесно четене. - person Gareth Latty; 21.04.2013
comment
Харесвам тези отговори. В момента съм на python 2.7. Безопасно ли е да преминете към 3.3 и да използвате по-ранна версия на pyodbc? Базата данни е вертикална. Също така, има ли начин да се коригира влагането, заради любопитството? - person Caleb; 21.04.2013
comment
Можете да поправите влагането по абсолютно същия начин: [sublist[0] + sublist[1:] for sublist in nested] (2.7) или [head + rest for head, *rest in nested] (3.x). - person DSM; 21.04.2013
comment
@DSM, ако публикувате това като пълен отговор, определено ще му дам +1 - person Caleb; 21.04.2013
comment
@Caleb, просто предполагам, че би било по-добре да остана на 2.7 за съвместимост - person jamylak; 21.04.2013