@@ -164,25 +164,23 @@ def _split_optional_netmask(address):
164164
165165
166166def _find_address_range (addresses ):
167- """Find a sequence of IPv#Address.
167+ """Find a sequence of sorted deduplicated IPv#Address.
168168
169169 Args:
170170 addresses: a list of IPv#Address objects.
171171
172- Returns:
173- A tuple containing the first and last IP addresses in the sequence,
174- and the number of distinct IP addresses in the sequence.
172+ Yields:
173+ A tuple containing the first and last IP addresses in the sequence.
175174
176175 """
177- first = last = addresses [0 ]
178- i = 1
179- for ip in addresses [1 :]:
180- if ip ._ip == last ._ip + 1 :
181- last = ip
182- i += 1
183- else :
184- break
185- return (first , last , i )
176+ it = iter (addresses )
177+ first = last = next (it )
178+ for ip in it :
179+ if ip ._ip != last ._ip + 1 :
180+ yield first , last
181+ first = ip
182+ last = ip
183+ yield first , last
186184
187185
188186def _count_righthand_zero_bits (number , bits ):
@@ -323,7 +321,6 @@ def collapse_addresses(addresses):
323321 TypeError: If passed a list of mixed version objects.
324322
325323 """
326- i = 0
327324 addrs = []
328325 ips = []
329326 nets = []
@@ -349,14 +346,13 @@ def collapse_addresses(addresses):
349346 ip , nets [- 1 ]))
350347 nets .append (ip )
351348
352- # sort
353- ips = sorted (ips )
349+ # sort and dedup
350+ ips = sorted (set ( ips ) )
354351
355352 # find consecutive address ranges in the sorted sequence and summarize them
356- while i < len (ips ):
357- (first , last , items ) = _find_address_range (ips [i :])
358- i = items + i
359- addrs .extend (summarize_address_range (first , last ))
353+ if ips :
354+ for first , last in _find_address_range (ips ):
355+ addrs .extend (summarize_address_range (first , last ))
360356
361357 return _collapse_addresses_internal (addrs + nets )
362358
0 commit comments