2015-05-08 6 views
2

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

a = [['he', 'goes'], 
    ['he does'], 
    ['one time'], 
    [('he','is'), ('she', 'went'), ('they', 'are')], 
    ['he', 'must'], 
    ['they use']] 

Я пытаюсь выровнять список таким образом, что это только список списков, без кортежей , Например:

a = [['he', 'goes'], 
    ['he does'], 
    ['one time'], 
    ['he','is'], 
    ['she', 'went'], 
    ['they', 'are'], 
    ['he', 'must'], 
    ['they use']] 

Я попытался с помощью itertools.chain.from_iterable() однако, что сглаживает все вложенные списки.

+1

Пожалуйста, покажите нам, что вы пробовали до сих пор. – Hexaholic

+1

Каков ваш реальный вопрос? – Paco

ответ

6
b = [] 
for x in a: 
    if isinstance(x[0], tuple): 
     b.extend([list(y) for y in x]) 
    else: 
     b.append(x) 
+1

Да, один из тех случаев, когда цикл яснее. Также может быть 'list (map (list, x))', btw. Не уверен, что лучше. –

+0

Очень читаемое решение. – GNMO11

5

Это решает ваш пример:

a = [list(strings) for sublist in a for strings in 
    ([sublist] if isinstance(sublist[0], str) else sublist)] 

Для каждого подсписка, который уже список строк, просто используйте подсписок. В противном случае перейдите через этот подсписчик.

Складывается ли это достаточно или ваши данные более сложны?

+0

Хорошее решение. Вы также можете сделать это '[list (c) for b in ...]', чтобы убедиться, что кортежи преобразованы в список. – poke

+1

Я не спускал вниз, но это очень трудно читать. Возможно, использование переменных с более чем одной буквой сделает ответ более удобным для пользователя - или объяснение. –

+0

@poke Правильно, забыл, спасибо. –

6

Используя выход из и python3:

from collections import Iterable 
def conv(l): 
    for ele in l: 
     if isinstance(ele[0], Iterable) and not isinstance(ele[0],str): 
      yield from map(list,ele) 
     else: 
      yield ele 

print(list(conv(a))) 
[['he', 'goes'], ['he does'], ['one time'], ['he', 'is'], ['she', 'went'], ['they', 'are'], ['he', 'must'], ['they use']] 

Для python2 вы можете перебрать в itertools.imap объект:

from collections import Iterable 
from itertools import imap 

def conv(l): 
    for ele in l: 
     if isinstance(ele[0], Iterable) and not isinstance(ele[0],basestring): 
      for sub in imap(list, ele): 
       yield sub 
     else: 
      yield ele 

print(list(conv(a))) 

Если у вас есть вложенные кортежи вам нужно будет добавить еще логика.

+0

Я попытался сменить «python to» на «python2», но не был допущен, потому что он слишком мал ... (и я не смею менять его). –

+0

@StefanPochmann, да, ура, отредактирован. –

Смежные вопросы