在Python中将多维列表转换为1D列表

时间:2010-06-02 22:08:06

标签: python

l=[[1,2],[3,4]]可以将sum(l,[])等多维列表转换为1D列表。有人可以解释一下这是怎么回事吗?

响应者说,这种技术只能用于“压扁”2D列表 - 它不适用于更高的多维列表。但如果重复,它确实如此。例如,如果A是3D列表,则sum(sum(A),[]),[])将A压缩为1D列表。

7 个答案:

答案 0 :(得分:43)

如果您的列表nested正如您所说,“2D”(意味着您只想向下一级,而nested的所有1级向下项目都是列表),一个简单的列表理解:

flat = [x for sublist in nested for x in sublist]

是我推荐的方法 - 比sum ming更有效(sum用于数字 - 这只是一个太多了懒得以某种方式阻止所有“求和”非数字的尝试...我是Python标准库中sum的原始提议者和第一个实现者,所以我想我应该知道; - )。

如果你想“尽可能深入”(对于深度嵌套的列表),递归是最简单的方法,尽管通过消除递归可以获得更高的性能(以更高的复杂性为代价)。

This recipe建议使用递归解决方案,递归消除和其他方法 (所有这些都很有启发性,但没有一个像我在本回答中提到的那样简单)。

答案 1 :(得分:35)

sum使用+运算符将序列添加到一起。例如sum([1,2,3]) == 6。第二个参数是可选的起始值,默认为0,例如sum([1,2,3], 10) == 16

在您的示例中,[] + [1,2] + [3,4] {2}列表中的+将它们连接在一起。因此,结果为[1,2,3,4]

需要空列表作为sum的第2个参数,因为如上所述,默认值是sum添加到0(即0 + [1,2] + [3,4]),这将导致< em> +:'int'和'list'

不支持的操作数类型

这是sum的帮助的相关部分:

  

sum(sequence [,start]) - &gt;值

     

返回序列的总和   数字(非字符串)加上值   参数'start'(默认为   到0)。

注意

正如wallacoloo所述,这是用于展平任何多维列表的一般解决方案。由于上述行为,它仅适用于1D列表的列表。

<强>更新

有关拼平1级嵌套的方法,请参阅itertools页面中的此配方:

def flatten(listOfLists):
    "Flatten one level of nesting"
    return chain.from_iterable(listOfLists)

要展平更深层次的嵌套列表(包括不规则嵌套列表),请参阅accepted answerthis question(还有一些其他问题与该问题本身相关联。)

请注意,配方返回itertools.chain对象(可迭代),另一个问题的答案返回generator对象,因此您需要在调用list时将其中任何一个包装起来如果你想要完整的列表而不是迭代它。例如list(flatten(my_list_of_lists))

答案 2 :(得分:2)

对于任何类型的多元数组,此代码都将展平为一维:

def flatten(l):
    try:
        return flatten(l[0]) + (flatten(l[1:]) if len(l) > 1 else []) if type(l) is list else [l]
    except IndexError:
        return []

答案 3 :(得分:1)

在我看来,更像是在寻找最终答案:

[3, 7]

为此,您最好使用list comprehension

>>> l=[[1,2],[3,4]]
>>> [x+y for x,y in l]
[3, 7]

答案 4 :(得分:1)

我编写了一个使用递归进行多维展平的程序。如果有人对改进程序有任何意见,你总能看到我微笑:

def flatten(l):
    lf=[]
    li=[]
    ll=[]
    p=0
    for i in l:
        if type(i).__name__=='list':
           li.append(i)
        else:
           lf.append(i)
    ll=[x for i in li for x in i]
    lf.extend(ll)

    for i in lf:
        if type(i).__name__ =='list':
           #not completely flattened
           flatten(lf)
        else:
           p=p+1
           continue

    if p==len(lf):
       print(lf)

答案 5 :(得分:0)

我已经编写了此函数:

function App() {
  const [parentHeight, setParentHeight] = React.useState(200);
  const [parentWidth, setParentWidth] = React.useState(300);

  const [curve, setCurve] = React.useState(0);

  const childDiameter = 40;

  const rows = [
    { position: 0, seats: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] },
    { position: 1, seats: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] },
    { position: 2, seats: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] },
    { position: 3, seats: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] }
  ];

  const getCurve = (idx, length) => {
    return curve / ((idx - (length/2))*(idx - length/2) + idx);
  };
  
  return (
    <div>
      <div
        style={{
          position: "absolute",
          width: `${parentWidth}px`,
          height: `${parentHeight}px`,
          top: 100,
          left: 100,
          boxSizing: "border-box",
          display: "flex",
          flexWrap: "wrap"
        }}
      >
        {rows.map((row, rowIdx) => (
          <div>
            {row.seats.map((seat, idx) => (
              <div
                style={{
                  position: "absolute",
                  left: idx * (childDiameter + 10),
                  top:
                    rowIdx * (childDiameter + 10) +
                    getCurve(idx, row.seats.length),
                  backgroundColor: "grey",
                  border: "3px solid grey",
                  borderRadius: "50%",
                  width: childDiameter,
                  height: childDiameter
                }}
              >
                {idx}
              </div>
            ))}
          </div>
        ))}
      </div>
      <input
        id="typeinp"
        type="range"
        min="-200"
        max="200"
        value={curve}
        onChange={evt => setCurve(parseInt(evt.target.value))}
        step="1"
      />
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

它也很好!

答案 6 :(得分:-1)

+运算符连接列表,起始值为[]空列表。