LINUX.ORG.RU

[python] хитро преобразовать массив

 


0

0

Доброго времени суток.

Имеется такой список словарей

[{'ip': '0.0.0.0', 'port': '67'}, {'ip': '0.0.0.0', 'port': '137'}, {'ip': '0.0.0.0', 'port': '1701'}, {'ip': '0.0.0.0', 'port': '8303'}, {'ip': '10.0.0.1', 'port': '53'}, {'ip': '127.0.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '137'}, {'ip': '192.168.0.1', 'port': '138'}]

Как из него можно получить что-то вроде следующего

[{'ip':'0.0.0.0', 'port':'67 137 1701 8303'}, {'ip':'10.0.0.1', 'port':'53'}, {'ip':'127.0.0.1', 'port':'53'},{'ip':'192.168.0.1','port':'53 137 138'}]

По большому счету всеравно, как будет представлен список портов, хоть строка, хоть список. Больше часа уже голову ломаю, так и не придумал способа.


Straightforward решение:

~/test :) % python untitled.py
[{'ip': '192.168.0.1', 'port': '53 137 138'}, {'ip': '10.0.0.1', 'port': '53'}, {'ip': '0.0.0.0', 'port': '67 137 1701 8303'}, {'ip': '127.0.0.1', 'port': '53'}]
~/test :) % cat untitled.py 
data = [{'ip': '0.0.0.0', 'port': '67'}, {'ip': '0.0.0.0', 'port': '137'}, {'ip': '0.0.0.0', 'port': '1701'}, {'ip': '0.0.0.0', 'port': '8303'}, {'ip': '10.0.0.1', 'port': '53'}, {'ip': '127.0.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '137'}, {'ip': '192.168.0.1', 'port': '138'}]

res = {}

for d in data:
        if d['ip'] in res:
                res[d['ip']] = res[d['ip']] + " " + d['port']
        else:
                res[d['ip']] = d['port']

result = []

for (k, v) in res.items():
        result.append({'ip':k, 'port': v})

print result 

Pi ★★★★★
()

Элементарно же:

l = [{'ip': '0.0.0.0', 'port': '67'}, {'ip': '0.0.0.0', 'port': '137'}, {'ip': '0.0.0.0', 'port': '1701'}, {'ip': '0.0.0.0', 'port': '8303'}, {'ip': '10.0.0.1', 'port': '53'}, {'ip': '127.0.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '137'}, {'ip': '192.168.0.1', 'port': '138'}]

newl = [{'ip':k,'port':" ".join(v)} for (k,v) in sorted(dict([(ip,[i['port'] for i in l if i['ip']==ip]) for ip in dict([(j['ip'],0) for j in l]).keys()]).items())]

print newl

lomereiter
()

$ cat groupby.py
from operator import itemgetter
from itertools import groupby
from pprint import pprint

data = [{'ip': '0.0.0.0', 'port': '67'}, {'ip': '0.0.0.0', 'port': '137'}, {'ip': '0.0.0.0', 'port': '1701'}, {'ip': '0.0.0.0', 'port': '8303'}, {'ip': '10.0.0.1', 'port': '53'}, {'ip': '127.0.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '137'}, {'ip': '192.168.0.1', 'port': '138'}] 

grouped = groupby(data, itemgetter('ip'))
result = [dict(ip=ip, port=map(itemgetter('port'), ports))
          for ip, ports in grouped]

pprint (result)


$ python groupby.py 
[{'ip': '0.0.0.0', 'port': ['67', '137', '1701', '8303']},
 {'ip': '10.0.0.1', 'port': ['53']},
 {'ip': '127.0.0.1', 'port': ['53']},
 {'ip': '192.168.0.1', 'port': ['53', '137', '138']}]

registration_sucks
()
Ответ на: комментарий от lomereiter

> newl = [{'ip':k,'port':" ".join(v)} for (k,v) in sorted(dict([(ip,[i['port'] for i in l if i['ip']==ip]) for ip in dict([(j['ip'],0) for j in l]).keys()]).items())]

Вот за такое руки нужно отрывать. Ведь кому-нибудь может придется это все поддерживать.

alexru ★★★★
()
Ответ на: комментарий от registration_sucks

>from operator import itemgetter
>from itertools import groupby

>from pprint import pprint


за такое тоже можно руки оторвать, ибо здесь ооп нафиг не упёрлось

dimon555 ★★★★★
()

Здравствуйте, это конкурс Obfuscated Python?

tailgunner ★★★★★
()
Ответ на: комментарий от dimon555

> за такое тоже можно руки оторвать, ибо здесь ооп нафиг не упёрлось

Где ж тут ооп? Тут скорее фп.

const86 ★★★★★
()

>>> a = [{'ip': '0.0.0.0', 'port': '67'}, {'ip': '0.0.0.0', 'port': '137'}, {'ip': '0.0.0.0', 'port': '1701'}, {'ip': '0.0.0.0', 'port': '8303'}, {'ip': '10.0.0.1', 'port': '53'}, {'ip': '127.0.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '53'}, {'ip': '192.168.0.1', 'port': '137'}, {'ip': '192.168.0.1', 'port': '138'}]
>>> b = {}
>>> for i in a:
...     b.setdefault(i['ip'], []).append(i['port'])
... 
>>> b
{'192.168.0.1': ['53', '137', '138'], '10.0.0.1': ['53'], '0.0.0.0': ['67', '137', '1701', '8303'], '127.0.0.1': ['53']}

baverman ★★★
()
Ответ на: комментарий от registration_sucks

> from operator import itemgetter

> from itertools import groupby

Спасибо, понравилось.

AlexKiriukha ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.