gpt4 book ai didi

python - 使用列表时的排序问题

转载 作者:太空宇宙 更新时间:2023-11-03 15:23:59 24 4
gpt4 key购买 nike

我有一个包含 IP 地址列表的 .txt 文件:

111.67.74.234:8080
111.67.75.89:8080
12.155.183.18:3128
128.208.04.198:2124
142.169.1.233:80

不过还有很多:)

无论如何,使用 Python 将它导入到一个列表中,我试图让它对它们进行排序,但我遇到了麻烦。有人有什么想法吗?

编辑:好吧,因为那是含糊不清的,这就是我所拥有的。

f = open("/Users/jch5324/Python/Proxy/resources/data/list-proxy.txt", 'r+')
lines = [x.split() for x in f]
new_file = (sorted(lines, key=lambda x:x[:18]))

最佳答案

当您希望它们按数字排序时,您可能会通过 ascii 字符串比较('.' < '5' 等)对它们进行排序。尝试将它们转换为整数元组,然后排序:

def ipPortToTuple(string):
"""
'12.34.5.678:910' -> (12,34,5,678,910)
"""
ip,port = string.strip().split(':')
return tuple(int(i) for i in ip.split('.')) + (port,)

with open('myfile.txt') as f:
nonemptyLines = (line for line in f if line.strip()!='')
sorted(nonemptyLines, key=ipPortToTuple)

编辑:您得到的 ValueError 是因为您的文本文件并不像您暗示的那样完全采用 #.#.#.#:# 格式。 (可能有注释或空行,但在这种情况下,错误会提示一行中包含多个“:”。)您可以使用调试技术来解决您的问题,方法是捕获异常并发出有用的信息调试数据:

def tryParseLines(lines):
for line in lines:
try:
yield ipPortToTuple(line.strip())
except Exception:
if __debug__:
print('line {} did not match #.#.#.#:# format'.format(repr(line)))

with open('myfile.txt') as f:
sorted(tryParseLines(f))

我在上面有点马虎,因为它仍然允许一些无效的 IP 地址通过(例如#.#.#.#.#,或 257.-1.#.#)。下面是一个更彻底的解决方案,它允许您执行诸如将 IP 地址与 < 进行比较之类的操作。运算符,也使排序自然地工作:

#!/usr/bin/python3

import functools
import re

@functools.total_ordering
class Ipv4Port(object):
regex = re.compile(r'(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):(\d{1,5})')

def __init__(self, ipv4:(int,int,int,int), port:int):
try:
assert type(ipv4)==tuple and len(ipv4)==4, 'ipv4 not 4-length tuple'
assert all(0<=x<256 for x in ipv4), 'ipv4 numbers not in valid range (0<=n<256)'
assert type(port)==int, 'port must be integer'
except AssertionError as ex:
print('Invalid IPv4 input: ipv4={}, port={}'.format(repr(ipv4),repr(port)))
raise ex

self.ipv4 = ipv4
self.port = port

self._tuple = ipv4+(port,)

@classmethod
def fromString(cls, string:'12.34.5.678:910'):
try:
a,b,c,d,port = cls.regex.match(string.strip()).groups()
ip = tuple(int(x) for x in (a,b,c,d))
return cls(ip, int(port))
except Exception as ex:
args = list(ex.args) if ex.args else ['']
args[0] += "\n...indicating ipv4 string {} doesn't match #.#.#.#:# format\n\n".format(repr(string))
ex.args = tuple(args)
raise ex

def __lt__(self, other):
return self._tuple < other._tuple
def __eq__(self, other):
return self._tuple == other._tuple

def __repr__(self):
#return 'Ipv4Port(ipv4={ipv4}, port={port})'.format(**self.__dict__)
return "Ipv4Port.fromString('{}.{}.{}.{}:{}')".format(*self._tuple)

然后:

def tryParseLines(lines):
for line in lines:
line = line.strip()
if line != '':
try:
yield Ipv4Port.fromString(line)
except AssertionError as ex:
raise ex
except Exception as ex:
if __debug__:
print(ex)
raise ex

演示:

>>> lines = '222.111.22.44:214 \n222.1.1.1:234\n 23.1.35.6:199'.splitlines()
>>> sorted(tryParseLines(lines))
[Ipv4Port.fromString('23.1.35.6:199'), Ipv4Port.fromString('222.1.1.1:234'), Ipv4Port.fromString('222.111.22.44:214')]

将值更改为例如 264......-35...将导致相应的错误。

关于python - 使用列表时的排序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9951908/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com