我正在尝试修复我正在使用的列表中一些损坏的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]
...这会产生语法错误...
关于我在做什么错的任何想法吗?
答案 0 :(得分:6)
如果仅使用常规循环,则此方法更简单。列表理解的问题是,您没有对第一个列表的每个元素创建新列表的元素的统一操作。 (将列表理解视为map
和filter
的组合。您可以将一个旧值映射到一个新值,也可以删除一个旧值,但是不能将多个旧值组合成一个一个新值。)
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