使用理解条件有条件地与先前的列表条目连接

时间:2019-02-14 19:17:21

标签: python python-3.x list-comprehension

我正在尝试修复我正在使用的列表中一些损坏的linux路径。

列表:

mylist = ['/root/path/path', '/cat', '/dog', '/root/path/path', '/blue', '/red']

要求:

如果元素不是以'/root'开头,请连接到元素左侧。

到目前为止的代码:

mylist2 = [''.join(x) for x in mylist]

print(mylist2)

预期输出:

['/root/path/path/cat/dog', '/root/path/path/blue/red']

实际输出:

['/root/path/path', '/cat', '/dog', '/root/path/path', '/blue', '/red']

我也尝试过:

mylist2 = [''.join(x) if myroot not x for mylist]

...这会产生语法错误...

关于我在做什么错的任何想法吗?

2 个答案:

答案 0 :(得分:6)

如果仅使用常规循环,则此方法更简单。列表理解的问题是,您没有对第一个列表的每个元素创建新列表的元素的统一操作。 (将列表理解视为mapfilter的组合。您可以将一个旧值映射到一个新值,也可以删除一个旧值,但是不能将多个旧值组合成一个一个新值。)

mylist2 = []
for path in mylist:
    if path.startswith('/root'):
        mylist2.append(path)
    else:
        mylist2[-1] += path

(这只是部分正确;它假设mylist的第一个元素实际上将以/root开头,因此如果mylist2[-1]为空,将永远不会使用mylist2

答案 1 :(得分:2)

这是一种使用列表理解的方法:

mylist2 = ['/root' + x for x in ''.join(mylist).split('/root') if x]  # if x eliminates the empty split elements

# ['/root/path/path/cat/dog', '/root/path/path/blue/red']

由于您的目标基本上是将所有内容连接在一起,然后按/root进行拆分,因此列表理解这一行就可以做到这一点,并将/root添加到每个元素中。

但是正如您所看到的,仅给出代码,@ chepner的答案就更容易理解和清楚了。仅仅因为列表理解存在并不意味着它应该成为您的首选。

我还要注意,如果您的任何元素中都存在/root(不一定在开头),由于拆分,此代码也会将其分开,因此它不像显式遍历循环那样精确。 。如果您想处理这种情况,它将变得非常难看...:

['/root' + y for y in ''.join("_" + x if x.startswith("/root") else x for x in lst).split("_/root") if y]

# eww