I have a list as:
['Title', 'Text', 'Title', 'Title', 'Text', 'Title', 'Text', 'List', 'Text', 'Title', 'Text', 'Text']
I want every element to be connected to element 'Title" before the element. For example, Text at index 1 is connected to Title at index 0, Title at index 2 would not be connected to any element, because it has another title after it. Text at index 4 is connected to title 3, similarly Text at position 10,11 will be connected to Title at index 9.
This is the expected output:
{1:0,4:3,6:5,7:5,8:5,10:9,11:9}
How can I do that?
CodePudding user response:
You can use a loop:
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)
Output: {1: 0, 4: 3, 6: 5, 7: 5, 8: 5, 10: 9, 11: 9}
CodePudding user response:
Don't take this as good practice, but I was trying to have fun with the :=
walrus operator and do it all in one comprehension.
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=}")
#output:
li2={1: 0, 4: 3, 6: 5, 8: 5, 10: 9, 11: 9}
In some defense of this unintuitive code list comprehensions are usually faster than equivalent for loop constructs. Usually => not in this case, where mozway's answer was faster.
CodePudding user response:
Basic logic is to find all postions of root Title
and just place the last smaller than current position to current none root element.
Code:
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]}
Output:
{1: 0, 4: 3, 6: 5, 7: 5, 8: 5, 10: 9, 11: 9}
CodePudding user response:
One way you can do this (not very efficient but I do not have much time at them moment):
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'}
But this does not check if there is a 'Title' in your list, i.e. the list should always start with 'Title'.