2015-06-05 3 views
2

У меня есть файл с разными IP-адресами.Python найти последнее вхождение в файл

192.168.11.2 
192.1268.11.3 
192.168.11.3 
192.168.11.3 
192.168.11.2 
192.168.11.5 

Это мой код до сих пор. Где я печатаю IP и происхождение, но как я могу узнать, когда было последнее событие для каждого из IP-адресов. Это простой способ сделать это?

liste = [] 

dit = {} 
file = open('ip.txt','r') 

file = file.readlines() 

for line in file: 
     liste.append(line.strip()) 

for element in liste: 
     if element in dit: 
       dit[element] +=1 
     else: 
       dit[element] = 1 

for key,value in dit.items(): 
     print "%s occurs %s times, last occurence at line" %(key,value) 

Выход:

192.1268.11.3 occurs 1 times, last occurence at line 
192.168.11.3 occurs 2 times, last occurence at line 
192.168.11.2 occurs 2 times, last occurence at line 
192.168.11.5 occurs 1 times, last occurence at line 

ответ

4

Попробуйте это:

liste = [] 

dit = {} 
file = open('ip.txt','r') 

file = file.readlines() 

for line in file: 
     liste.append(line.strip()) 

for i, element in enumerate(liste, 1): 
     if element in dit: 
       dit[element][0] += 1 
       dit[element][1] = i 
     else: 
       dit[element] = [1,i] 

for key,value in dit.items(): 
     print "%s occurs %d times, last occurence at line %d" % (key, value[0], value[1]) 
+0

Словарных значения (неизменные) кортежи, так что вы не можете добавить к первому элементу – jonrsharpe

+0

Измененным, что в список, спасибо – konart

+0

Не могли бы вы прокомментировать отредактированную часть? Я не знаю, что делать. –

0

Вы можете использовать другой словарь. В этом словаре вы сохраняете для каждой строки номер строки последнего вхождения и перезаписываете каждый раз, когда находите другое вхождение. В конце этого словаря у вас будет для каждой строки номер строки последнего вхождения.

Очевидно, вам нужно будет увеличивать счетчик для каждой прочитанной строки, чтобы знать, какую строку вы сейчас читаете.

1
last_line_occurrence = {} 
for element, line_number in zip(liste, range(1, len(liste)+1)): 
    if element in dit: 
      dit[element] +=1 
    else: 
      dit[element] = 1 
    last_line_occurrence[element] = line_number 

for key,value in dit.items(): 
    print "%s occurs %s times, last occurence at line %s" %(key,value, last_line_occurrence[key]) 
+0

1. Исправлено с 1 r:' last_line_occurence'. 2. Вам нужен 'len (liste) + 1':' range (1, 5) '==>' [1, 2, 3, 4] ', который не включает в себя 5. –

+0

@haivu Действительно, вы правы , Я отредактировал свой ответ. – PetMarion

3

Вот решение:

from collections import Counter 

with open('ip.txt') as input_file: 
    lines = input_file.read().splitlines() 

    # Find last occurrence, count 
    last_line = dict((ip, line_number) for line_number, ip in enumerate(lines, 1)) 
    ip_count = Counter(lines) 

    # Print the stat, sorted by last occurrence 
    for ip in sorted(last_line, key=lambda k: last_line[k]): 
     print '{} occurs {} times, last occurence at line {}'.format(
      ip, ip_count[ip], last_line[ip])    

Обсуждение

  • Я использую функцию enumerate генерировать номер строки (начиная с линии 1)
  • С последовательностью (ф, line_number), это легко создать словарь last_line где ключ является IP-адрес и значение последней строки это происходит
  • Чтобы подсчитать количество вхождений, я использую Counter класс --Очень простой
  • Если вы хотите, чтобы отчет, отсортированный по IP-адресу, используйте sorted(last_line)
  • Это решение имеет последствия производительности: он сканирует список IP-адресов дважды: один раз, чтобы вычислить last_line и один раз для расчета ip_count. Это означает, что это решение не может быть идеальным, если файл большой
+0

Почему вам нужно создать список всех строк с помощью 'lines = input_file.read(). Splitlines()'? –

+0

Как я уже говорил в своем сообщении, проблема с производительностью с моим решением заключается в том, что мне нужно дважды проверять список. Я создал список, так что мне не нужно дважды читать файл. –

+0

Вы можете просто 'file.seek (0)' и не читать весь контент в памяти. –

1

Это можно легко сделать в один проход, не читая весь файл в память:

from collections import defaultdict 
d = defaultdict(lambda: {"ind":0,"count":0}) 

with open("in.txt") as f: 
    for ind, line in enumerate(f,1): 
     ip = line.rstrip() 
     d[ip]["ind"] = ind 
     d[ip]["count"] += 1 

for ip ,v in d.items(): 
    print("IP {} appears {} time(s) and the last occurrence is at line {}".format(ip,v["count"],v["ind"])) 

Выход:

IP 192.1268.11.3 appears 1 time(s) and the last occurrence is at line 2 
IP 192.168.11.3 appears 2 time(s) and the last occurrence is at line 4 
IP 192.168.11.2 appears 2 time(s) and the last occurrence is at line 5 
IP 192.168.11.5 appears 1 time(s) and the last occurrence is at line 6 

Если вы хотите, чтобы заказ на IP-адресов, которые впервые столкнулись использовать OrderedDict:

from collections import OrderedDict 
od = OrderedDict() 
with open("in.txt") as f: 
    for ind, line in enumerate(f,1): 
     ip = line.rstrip() 
     od.setdefault(ip, {"ind": 0,"count":0}) 
     od[ip]["ind"] = ind 
     od[ip]["count"] += 1 

for ip ,v in od.items(): 
    print("IP {} appears {} time(s) and the last occurrence is at line {}".format(ip,v["count"],v["ind"])) 

Выход:

IP 192.168.11.2 appears 2 time(s) and the last occurrence is at line 5 
IP 192.1268.11.3 appears 1 time(s) and the last occurrence is at line 2 
IP 192.168.11.3 appears 2 time(s) and the last occurrence is at line 4 
IP 192.168.11.5 appears 1 time(s) and the last occurrence is at line 6 
Смежные вопросы