0

I have a list with the following structure [{key:[..,..]},...] and I am trying to group the output by the IP addresses.

my_list = [{'xxxxx1': ['123.123.123.1','hey','hello']},{'xxxxx2':['123.123.123.2','hi','HEY']},{'xxxxx3':['123.123.123.3','foo','bar']},{'xxxxx3':['123.123.123.2','foo','bar']}]


for item in my_list:
        for k in item:
            print(item[k])

Above code is printing the following:

['123.123.123.1', 'hey', 'hello']
['123.123.123.2', 'hi', 'HEY']
['123.123.123.3', 'foo', 'bar']
['123.123.123.2', 'foo', 'bar']

However, I am not sure how to group the output so it will look like following(notice 123.123.123.2 with two lines)

123.123.123.1
hey hello
123.123.123.2
hi HEY
foo bar
123.123.123.3
foo bar
monk
  • 1,953
  • 3
  • 21
  • 41

3 Answers3

4

You can make another dictionary to keep track of IP addresses. You can then iterate over the values to produce your desired output.

tracker = {}
for entry in my_list:
    for k,v in entry.items():
        if v[0] not in tracker.keys():
            tracker[v[0]] = [v[1:]] 
        else:
            tracker[v[0]].append(v[1:])

for k,v in tracker.items():
    print(k)
    for item in v:
        print(item)

This produces the following output:

123.123.123.1
['hey', 'hello']
123.123.123.2
['hi', 'HEY']
['foo', 'bar']
123.123.123.3
['foo', 'bar']
Sterling
  • 432
  • 2
  • 9
2

Great solution from @Sterling above.

Remember, just in case you need to print it out without the brackets for the list, you can do some string concatenation in the print statement.

my_list = [
    {"xxxxx1": ["123.123.123.1", "hey", "hello"]},
    {"xxxxx2": ["123.123.123.2", "hi", "HEY"]},
    {"xxxxx3": ["123.123.123.3", "foo", "bar"]},
    {"xxxxx3": ["123.123.123.2", "foo", "bar"]},
]

tracker = {}
for entry in my_list:
    for k,v in entry.items():
        if v[0] not in tracker.keys():
            tracker[v[0]] = [v[1:]] 
        else:
            tracker[v[0]].append(v[1:])

for k,v in tracker.items():
    print(k)
    for item in v:
        print(item[0] + " " + item[1])

enter image description here

swolfe2
  • 429
  • 1
  • 6
  • 24
1

Only one not so elegant part to get the first value of each dict:

first_values.append([i for i in item.values()][0]) 

It is copied from How to get the first value in a Python dictionary

Code

Simple code, for-loops and a dict. Explained with comments:

my_list = [
  {'xxxxx1': ['123.123.123.1','hey','hello']},
  {'xxxxx2': ['123.123.123.2','hi','HEY']},
  {'xxxxx3': ['123.123.123.3','foo','bar']},
  {'xxxxx3': ['123.123.123.2','foo','bar']}
]

# get the inner lists having IP as first element
first_values = []
for item in my_list:
    # for each element in the list (each dict), get the first value
    first_values.append([i for i in item.values()][0])
print(first_values)
# [['123.123.123.1', 'hey', 'hello'], ['123.123.123.2', 'hi', 'HEY'], ['123.123.123.3', 'foo', 'bar'], ['123.123.123.2', 'foo', 'bar']]

# convert the lists to a dict having IP as key, and words as value
ip_dict = {}
for element in first_values:
    ip = element[0]  # the fist element is the IP
    words = element[1:]  # the remaining element are words
    if ip not in ip_dict.keys():   # if IP not yet added (as key)
        ip_dict[ip] = words   # then add the new key, value pair
    else:
        ip_dict[ip] += words  # otherwise add the words to the existing value, which is a list of words
print(ip_dict)
# {'123.123.123.1': ['hey', 'hello'], '123.123.123.2': ['hi', 'HEY', 'foo', 'bar'], '123.123.123.3': ['foo', 'bar']}

From here you have a solid data structure as result. The ip_dict can be pretty-printed, e.g. using a for loop like:

for ip, words in ip_dict.items():
    print(f"{ip}\n{' '.join(words)}")
hc_dev
  • 8,389
  • 1
  • 26
  • 38