我有一个列表:
['Title', 'Text', 'Title', 'Title', 'Text', 'Title', 'Text', 'List', 'Text', 'Title', 'Text', 'Text']
我希望每个元素都连接到元素'Title"元素之前。例如,索引1处的Text连接到索引0处的Title,索引2处的Title不会连接到任何元素,因为它后面有另一个标题。索引4的文本连接到标题3,类似地,位置10,11的文本将连接到索引9的标题。
这是预期的输出:
{1:0,4:3,6:5,7:5,8:5,10:9,11:9}
我该怎么做呢?
你可以使用一个循环:
l = ['Title', 'Text', 'Title', 'Title', 'Text', 'Title', 'Text', 'List', 'Text', 'Title', 'Text', 'Text']
last = -1
out = {}
for i, v in enumerate(l):
if v == 'Title':
last = i
else:
out[i] = last
print(out)
输出:{1: 0, 4: 3, 6: 5, 7: 5, 8: 5, 10: 9, 11: 9}
不要认为这是一个很好的实践,但我试图在:=
海象操作符中获得乐趣,并在一次理解中完成所有操作。
prev = -1
li = ['Title', 'Text', 'Title', 'Title', 'Text', 'Title', 'Text', 'List', 'Text', 'Title', 'Text', 'Text']
li2 = {ix:prev
for ix, v
in enumerate(li)
if
#this first part is always True because of the +77
# why 77 rather than say 1? to avoid -1+1 => 0 if first is Text
#but it only stores prev on Title values using the walrus `:=`
((prev:= (ix if v == "Title" else prev))+77)
#we only want the Text Values
and v == "Text"
}
print(f"{li2=}")
#输出:
li2={1: 0, 4: 3, 6: 5, 8: 5, 10: 9, 11: 9}
在为这种不直观的代码辩护时,列表推导式通常比等价的for循环结构更快。通常=比;但在这种情况下,mozway的答案更快。
基本逻辑是找到根Title
的所有位置,并将最后一个比当前位置小的位置放置到当前无根元素
代码:
x= ['Title', 'Text', 'Title', 'Title', 'Text', 'Title', 'Text', 'List', 'Text', 'Title', 'Text', 'Text']
{i:[j for j, v in enumerate(x[:i]) if v==x[0]][-1] for i,v in enumerate(x) if v!=x[0]}
输出:
{1: 0, 4: 3, 6: 5, 7: 5, 8: 5, 10: 9, 11: 9}
有一种方法可以做到这一点(不是很有效):
x = ['Title', 'Text', 'Title', 'Title', 'Text', 'Title', 'Text', 'List', 'Text', 'Title', 'Text', 'Text']
d = {}
for i, ele in enumerate(x):
if ele != 'Title':
d[i] = i - x[:i+1][::-1].index('Title')
>>> print(d)
>>> {1: 0, 4: 3, 6: 5, 7: 5, 8: 5, 10: 9, 11: 9}
#oneliner:
{i: i-x[:i+1][::-1].index('Title') for i, ele in enumerate(x) if ele != 'Title'}
但是这不会检查你的列表中是否有一个'Title',也就是说列表应该总是以'Title'开头。
输出:
{1: 0, 4: 3, 6: 5, 7: 5, 8: 5, 10: 9, 11: 9}
根据公认的答案,哪个是正确的。