0

I have a list of lists, let's call it foo

foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]

and another list bar

bar = ['A', 'C', 'D', 'F', 'H']

I wanted search the elements of bar in foo and if they are find then the next element is to be picked and create a dictionary with keys as elements of bar.

What I tried:

pay = {}

for i in bar:
    for j in foo:
        for k in j:
            if i == k:
                try:
                    pay[i] = k+1
                except:
                    pay[i] = '-'

Expected Output:

pay = {'A':1,
'C':5,
'D':9,
'F':'-',
'H':'-'}
1
  • 1
    You can use for index, k in enumerate(j) and pay[i] = j[index+1] Commented May 31, 2021 at 7:01

7 Answers 7

1

You've missed,

  1. Accessing the proper index to find the next element.
  2. Using == operator instead of in property to check the value's presence in the list.

Solution:

bar = ['A', 'C', 'D', 'F', 'H']
foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]

output_dict = {}

for element in foo:
    for foo_element in element:
        if foo_element in bar:
            try:
                output_dict[foo_element] = element[element.index(foo_element) + 1]
            except:
                output_dict[foo_element] = '-'
print(output_dict)

Output:

{'D': '9', 'H': '-', 'F': '-', 'C': '5', 'A': '1'}
Sign up to request clarification or add additional context in comments.

Comments

1

I would normalize the data, i.e. flatten the foo and convert it to a dict of all pairs {item: next_item}.

Then just get the data from this dict.

foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
bar = ['A', 'C', 'D', 'F', 'H']

pdict = {k:v for s in foo for k, v in zip(s, s[1:])}
# print(pdict) # uncomment to check
pay = {k: pdict.get(k, '-') for k in bar}

print(pay) # {'A': '1', 'C': '5', 'D': '9', 'F': '-', 'H': '-'}

Comments

0

As @kuro mentioned, you can use enumerate function or else you can simply iterate over the the indices as below.

foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
bar = ['A', 'C', 'D', 'F', 'H']
pay = {}

for i in bar:
    for j in foo:
        for k in range(len(j)):
            if i == j[k]:
                try:
                    pay[i] = j[k + 1]
                except IndexError:
                    pay[i] = '-'

print(pay)

Output:

{'A': '1', 'C': '5', 'D': '9', 'F': '-', 'H': '-'}

Comments

0
list_of_lists = foo
flattened = [val for sublist in list_of_lists for val in sublist] + ['-']

pay = {}

for bar_val in bar:
    pos = flattened.index(bar_val)
    try:
        pay[bar_val] = int(flattened[pos+1])
    except ValueError as e:
        pay[bar_val] = '-'

print(pay)

Output:

{'A': 1, 'C': 5, 'D': 9, 'F': '-', 'H': '-'}

Comments

0

You can try to do it this way as well:

foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]
bar = ['A', 'C', 'D', 'F', 'H']
pay = dict()

# loop through bar
for i in range(len(bar)):
  # loop through foo
  for j in range(len(foo)):
    # loop through elements of foo
    for k in range(len(foo[j])):
      # check if data in foo matches element in bar
      if bar[i] == foo[j][k]:
        # check if data in foo is the last element in the sub-list
        if (len(foo[j]) > k+1):
          pay[bar[i]] = foo[j][k+1]
        else:
          pay[bar[i]] = '-'
      else:
        pass

# iterate through dict and print its contents
for k, v in pay.items():
    print(k, v)

Comments

0
def get_next(elt, sublist):
    
    try:
        return sublist[sublist.index(elt) + 1]
    except:
        return '-'

final_dict = { elt: get_next(elt, sub)  for sub in foo for elt in sub if elt in bar}

print(final_dict) # {'A': '1', 'C': '5', 'D': '9', 'F': '-', 'H': '-'}

1 Comment

Welcome to SO, don't hesitate top read stackoverflow.com/help/how-to-answer to improve the quality of answer you provide
0

Just another solution using generators:

foo = [['A', '1'], ['C', '5', 'D', '9', 'E'], ['F'], ['G', 'H']]

from itertools import chain

def get_pairs(it):
    stack = None
    while True:
        try:
            x = stack if stack else next(it)
            try:
                y = next(it)
                if y.isdigit():
                    yield x, y
                    stack = None
                else:
                    yield x, "-"
                    stack = y
            except StopIteration:
                yield x, "-"
                break
        except StopIteration:
            break

result = dict([item for item in get_pairs(chain.from_iterable(foo))])
print(result)

Which yields

{'A': '1', 'C': '5', 'D': '9', 'E': '-', 'F': '-', 'G': '-', 'H': '-'}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.