Wie kann ich Listen auflisten, ohne Strings zu spalten?

Ich möchte gerne Listen auflisten, die andere Listen enthalten können, ohne Strings auseinander zu brechen. Beispielsweise:

In [39]: list( itertools.chain(*["cat", ["dog","bird"]]) ) Out[39]: ['c', 'a', 't', 'dog', 'bird'] 

und ich möchte

 ['cat', 'dog', 'bird'] 

4 Solutions collect form web for “Wie kann ich Listen auflisten, ohne Strings zu spalten?”

 def flatten(foo): for x in foo: if hasattr(x, '__iter__'): for y in flatten(x): yield y else: yield x 

(Strings bequem nicht wirklich haben ein __iter__ Attribut, im Gegensatz zu ziemlich viel jedes andere iterable Objekt in __iter__ Sie jedoch, dass dies ändert sich in Python 3, so dass die oben genannten Code wird nur in Python 2.x arbeiten.)

Version für Python 3.x:

 def flatten(foo): for x in foo: if hasattr(x, '__iter__') and not isinstance(x, str): for y in flatten(x): yield y else: yield x 

Eine leichte Abänderung der Antwort von orip, die die Erstellung einer Zwischenliste vermeidet:

 import itertools items = ['cat',['dog','bird']] itertools.chain.from_iterable(itertools.repeat(x,1) if isinstance(x,str) else x for x in items) 

Ein Brute-Force-Weg wäre, um die Saite in ihre eigene Liste zu wickeln, dann verwenden itertools.chain

 >>> l = ["cat", ["dog","bird"]] >>> l2 = [([x] if isinstance(x,str) else x) for x in l] >>> list(itertools.chain(*l2)) ['cat', 'dog', 'bird'] 
 def squash(L): if L==[]: return [] elif type(L[0]) == type(""): M = squash(L[1:]) M.insert(0, L[0]) return M elif type(L[0]) == type([]): M = squash(L[0]) M.append(squash(L[1:])) return M def flatten(L): return [i for i in squash(L) if i!= []] >> flatten(["cat", ["dog","bird"]]) ['cat', 'dog', 'bird'] 

Hoffe das hilft

Python ist die beste Programmiersprache der Welt.