1

I have a list of lists that looks as follows.

names_table = [["Jerry", "A"],[ "Jerry", "B"], ["Jerry", "C"], ["George","C"], ["George","D"], ["George","E"], ["Elaine","A"], ["Kramer","E"], ["Kramer","F"] ]

My objective is to obtain an output list of lists in which each name only appears once, such as:

[["Jerry", ["A", "B", "C"]],["George", ["C", "D", "E"]], ["Elaine", ["A"]], ["Kramer", ["E", "F"]]]

My attempt:

I've approached this by deriving a list that contains all names just once

names = ["Jerry", "George", "Elaine", "Kramer"]

And then two for loops with a while statement, but the program enters into an infinite loop.

How could I fix this?

output = []

for row in names_table:
    for name in names:
        while name in row[0]:
            letters = []
            letters.append(row[1])
        output_row = [name, letters]
        output.append(output_row)
        break
                         

3 Answers3

4

It will be simpler to use a dict with dict.setdefault

Ex:

result = {}

for name, item in names_table:
    result.setdefault(name, []).append(item)

print(result)
# OR
print([[k] + [v] for k, v in result.items()])

Output:

{'Jerry': ['A', 'B', 'C'], 'George': ['C', 'D', 'E'], 'Elaine': ['A'], 'Kramer': ['E', 'F']}
[['Jerry', ['A', 'B', 'C']], ['George', ['C', 'D', 'E']], ['Elaine', ['A']], ['Kramer', ['E', 'F']]]
Rakesh
  • 81,458
  • 17
  • 76
  • 113
  • Thanks a lot. I'm a real noob here, so could you please explain what ```result.setdefault(name, []).append(item)``` does? I'm having a hard time parsing it. – linguist_at_large Jun 02 '21 at 12:37
  • 1
    Hope this helps..https://stackoverflow.com/questions/3483520/use-cases-for-the-setdefault-dict-method – Rakesh Jun 02 '21 at 12:41
2

The reason you while loop got stuck is because a while loop does not use an iterator, but rater uses an condition to keep running. The condition you used name in row[0] does not change in the loop, and therefore your loop keeps running.

For the rest of you problem I recommend using a dictionary. In a dictionary you can more easily assign values to keys(the names of the persons you are using). The example below creates a dict that looks like your objective array. If you really need and array, you can later on convert this dict to an array.

Example:

names_table = [["Jerry", "A"],[ "Jerry", "B"], ["Jerry", "C"], ["George","C"], ["George","D"], ["George","E"], ["Elaine","A"], ["Kramer","E"], ["Kramer","F"] ]

objective_dict = {}

for elm in names_table:
    
    # if the name of the person is not yet in the dict, add a name to the dict
    if not (elm[0] in objective_dict):
        objective_dict[elm[0]] = []
    
    # append the list of the user with the new value
    objective_dict[elm[0]].append(elm[1])

Result:

{'Jerry': ['A', 'B', 'C'],
 'George': ['C', 'D', 'E'],
 'Elaine': ['A'],
 'Kramer': ['E', 'F']}
Thijs Ruigrok
  • 547
  • 2
  • 12
1

you can try using defaultdict()

from collections import defaultdict

com_names= defaultdict(list)
for i in names_table:
    com_names[i[0]].append(i[1])
 
com_names
Ade_1
  • 1,480
  • 1
  • 6
  • 17