2010-03-29 94 views
2

我知道这是非常类似其他一些问题,但我不能完全得到这个功能正常工作。将参数转换为平面列表?

def flatten(*args): 
    return list(item for iterable in args for item in iterable) 

我在寻找的输出是:

flatten(1) -> [1] 
flatten(1,[2]) -> [1, 2] 
flatten([1,[2]]) -> [1, 2] 

目前的功能,这是我从另一个SO回答了,似乎并没有在所有产生正确的结果:

>>> flatten([1,[2]]) 
[1, [2]] 
+1

发布您的解决方案作为答案,并接受该答案。保持网站更清洁:) – Powertieke 2010-03-29 06:57:59

+0

我也更新了我的答案 - 您自己找到的答案是一个小整齐。 ) – 2010-03-29 06:59:11

回答

6

要获得快速解决方案,只需使用第二个函数并使其递归即可。

def flatten(*args): 
    output = [] 
    for arg in args: 
     if hasattr(arg, '__iter__'): 
      output.extend(flatten(*arg)) 
     else: 
      output.append(arg) 
    return output 
+0

试验__iter__不适用于散列工作,所以: – 2011-08-04 05:31:51

+0

样品为奇怪词典的结果: >>> DEF弄平(*参数): ...输出= [] ...用于在args ARG : ...如果hasattr(arg,'__iter__'): ... output.extend(flatten(* arg)) ... else: ... output.append(arg) ... return输出 ... >>> adict = {1:2,3:4,5:6} >>> blist = ['a','b','c'] >>> raw = [ adist,blist] >>> flatten(raw) [1,3,5,'a','b','c'] – 2011-08-04 05:39:52

+0

迭代ove字典产生它的关键。由于原来的问题没有说明字典所需的输出,为什么这个输出很奇怪? – 2011-08-09 21:16:44

4

如果要拼合任意嵌套列表,你需要一个递归函数:

def flatten(ls): 
    if isinstance(ls, list): 
    return [fa for a in ls for fa in flatten(a)] 
    else: 
    return [ls] 

(如果你希望使用发电机,而不是返回列表扁平化,这可能更有效率的大结构。 )

该功能还可以重复使用以产生一个函数,它的多个参数:

def pflatten(*ls): 
    return flatten(list(ls)) 
+0

输入参数应该是'* ls'。这确实有所作为,不是吗? 'hasattr(a,'__iter __')'比'isinstance'稍微多用一些吗? – mpen 2010-03-30 01:22:43

+0

@Mark:目前这个函数只有一个参数,如果它是一个列表,它会使它变平。它也可以用'* ls'完成,这样函数就有几个参数并且创建一个连续的扁平列表。我想说,你喜欢什么样的界面只是品味的问题。类似于'isinstance(a,list)'与'hasattr(a,'__iter __')':这只取决于您给它一个列表集合的列表时想要的结果。一组列表或所有集合中所有元素的列表?根据您的要求,其中一个或另一个会更可取。 – sth 2010-03-30 01:37:25

+0

是的,但这个问题是关于后者('* ls')的具体问题。我看到你关于集合的观点,尽管......并没有计划使用这些集合,但是元组肯定应该被转换为平面列表。 – mpen 2010-03-30 01:52:18

-1

解决它......

def flatlist(*args): 
    lst = [] 
    for a in args: 
     if hasattr(a, '__iter__'): lst.extend(flatlist(*a)) 
     else: lst.append(a) 
    return lst 
1

检查__ ITER __存在压扁字典时可以说是相当奇怪:

>>> def flatten(*args): 
...  output = [] 
...  for arg in args: 
...   if hasattr(arg, '__iter__'): 
...    output.extend(flatten(*arg)) 
...   else: 
...    output.append(arg) 
...  return output 
... 
>>> adict = {1:2, 3:4, 5:6} 
>>> blist = ['a', 'b', 'c'] 
>>> raw = [adict, blist] 
>>> flatten(raw) 
[1, 3, 5, 'a', 'b', 'c'] 

我觉得应该压平仅列表和元组的工作:

import types 

def flatten(*args): 
    output = [] 
    for arg in args: 
     if isinstance(arg, (types.ListType, types.TupleType)): 
      output.extend(flatten(*list(arg))) 
     else: 
      output.append(arg) 
    return output 

adict = {1:2, 3:4, 5:6} 
blist = ['a', 'b', 'c'] 
raw = [adict, blist] 
print flatten(raw)