Learning python with day to day stuff I normally do in other languages. I am parsing a netstat dump file to get a sorted unique list of remote IPs. I get the ip addresses from a text file and read them into an array (line by line).
x.xx.xxx.xxx
yy.yy.yyy.yyy
etc.
I found code that sorts the array:
import ipaddress
new_list = []
for element in IP_Array:
new_list.append(ipaddress.ip_address(element))
new_list.sort()
but the output is: [IPv4Address('x.xx.xx.xxx'), ...
The sorting is correct but the output is more than just the IP address. How do I get the output array just the IP address without [IPv4Address('') so I can remove duplicates in the next step?
what you have is list of
IPv4Address
objects. When you print a list you get the representation (i.e.
__repr__()
) of the individual elements in the list.
It looks like you expect to get a str, (i.e.
__str__()
) for each element
import ipaddress
spam = [ipaddress.ip_address('192.168.0.1'), ipaddress.ip_address('192.168.0.2')]
eggs = [str(ipadd) for ipadd in spam]
print(spam)
print(eggs)
for ipadd in spam:
print(ipadd)
Output:
[IPv4Address('192.168.0.1'), IPv4Address('192.168.0.2')]
['192.168.0.1', '192.168.0.2']
192.168.0.1
192.168.0.2
(Nov-09-2020, 03:08 PM)snichols Wrote: [ -> ]so I can remove duplicates in the next step
You don't need to do so, to remove the duplicates
import ipaddress
spam = [ipaddress.ip_address('192.168.0.1'), ipaddress.ip_address('192.168.0.2'), ipaddress.ip_address('192.168.0.1')]
print(spam)
print(list(set(spam)))
Output:
[IPv4Address('192.168.0.1'), IPv4Address('192.168.0.2'), IPv4Address('192.168.0.1')]
[IPv4Address('192.168.0.2'), IPv4Address('192.168.0.1')]
Note,
set
is unordered collections, so no guarantees about the order
From buran's answer one could easily conclude that in order to get sorted unique ip addresses one should first uniquify and then sort. As
sorted()
takes any iterable and returns list one can just apply it to set and get sorted list:
>>> import ipaddress
>>> spam = [ipaddress.ip_address('192.168.0.1'), ipaddress.ip_address('192.168.0.2'), ipaddress.ip_address('192.168.0.1')]
>>> sorted(set(spam))
[IPv4Address('192.168.0.1'), IPv4Address('192.168.0.2')]
As far as conversion goes:
from Python 3.9 there is also
IPv4Address.__format__(fmt) for converting into other types (string, binary, hex).
Similarly to
str()
there is also possibility to convert to integer with
int()
(Nov-10-2020, 09:22 AM)perfringo Wrote: [ -> ]in order to get sorted unique ip addresses one should first uniquify and then sort.
I didn't go into details about sorting, because from OP it looked like a means to find the unique ip addresses.
(Nov-10-2020, 09:22 AM)perfringo Wrote: [ -> ]from Python 3.9 there is also IPv4Address.__format__(fmt) for converting into other types (string, binary, hex).
great point, just to add that normally
.__format__()
is not meant to be invoked directly. I will just copy the example from the docs
>>> format(ipaddress.IPv4Address('192.168.0.1'))
'192.168.0.1'
>>> '{:#b}'.format(ipaddress.IPv4Address('192.168.0.1'))
'0b11000000101010000000000000000001'
>>> f'{ipaddress.IPv6Address("2001:db8::1000"):s}'
'2001:db8::1000'
>>> format(ipaddress.IPv6Address('2001:db8::1000'), '_X')
'2001_0DB8_0000_0000_0000_0000_0000_1000'
>>> '{:#_n}'.format(ipaddress.IPv6Address('2001:db8::1000'))
'0x2001_0db8_0000_0000_0000_0000_0000_1000'
I often use the fact, that a dict is a set without values, but since Python 3.6 the order is preserved.
So using
list(dict.fromkey(iterable))
will keep the order from the original iterable, but will remove duplicates.
from ipaddress import ip_address
spam = [ip_address('192.168.0.1'), ip_address('192.168.0.2'), ip_address('192.168.0.1')]
unique_preserved_order = list(dict.fromkeys(spam))
Thanks all for the info. I have my code de-duped and sorted. This is the first thing I have tried with python and there is so much to it, but I am liking it.