我有一個如下所示的 csv 檔案:
IP Address,Port,Protocol,State
192.168.3.1,53,tcp,open
192.168.13.100,80,tcp,open
192.168.3.1,443,tcp,close
192.168.3.71,1080,tcp,open
192.168.3.7,8888,tcp,open
192.168.23.12,80,tcp,filtered
192.168.3.12,443,tcp,open
192.168.3.12,631,tcp,open
我如何在 python 3 中按 IP 地址,然后按埠號排序?
我嘗試使用這個:
#!/bin/python3
# import modules
import csv, ipaddress
data = csv.reader(open('list.csv'),delimiter=',')
data = sorted(data, key = ipaddress.IPv4Address)
print('After sorting:')
print(data)
但我得到了一個 ipaddress.AddressValueError: Only decimal digits permitted in "['192" in "['192.168.3.1', '53', 'tcp', 'open']"
按ip地址排序后,代碼接下來應該檢查埠,因為有可能ip地址相同但埠不同。
一個多星期以來一直試圖解決這個問題。謝謝。
uj5u.com熱心網友回復:
第一個問題是來自 csv 閱讀器的資料包含標題行。要跳過第一行,只需在執行其他任何操作之前從閱讀器中讀取一行。
data = csv.reader(open('list.csv'),delimiter=',')
next(data) # Consumes the header line
data = sorted(...)
旁注:使用with以便在退出with塊時自動關閉檔案。
with open('list.csv') as file:
data = csv.reader(file)
next(data)
data = sorted(...)
現在,該key引數接受一個函式并將您正在排序的可迭代物件的每個元素傳遞給該函式。現在你data是一個可迭代的,其中每個元素都是一個代表 csv 檔案每一行的串列。您不想為每一行傳遞整個串列,您只想傳遞所述串列的第一個元素。您可以使用lambda 運算式作為獲取每個串列的鍵,并僅將第一個元素傳遞給ipaddress.IPv4Address。
data = sorted(data, key = lambda row: ipaddress.IPv4Address(row[0]))
由于您還想按埠排序,您可以讓 lambda 回傳一個包含 IP 地址和埠號的元組。
data = sorted(data, key = lambda row: (ipaddress.IPv4Address(row[0]), row[1]))
如果您將第一列轉換為IPv4Address物件data本身,您可能會發現它很有用,以便您可以在其他地方使用它們。在這種情況下,請逐行讀取您的 csv 檔案并在對其進行排序之前執行此操作。
with open('list.csv') as file:
reader = csv.reader(file)
next(reader)
data = []
for row in reader:
row[0] = ipaddress.IPv4Address(row[0])
data.append(row)
data.sort()
在這里,您不需要使用 lambda 函式,因為串列比較會自動比較第一個元素,然后是第二個元素,依此類推,并且行的元素已經是正確的比較型別。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/312311.html
