Próbuję utworzyć program w języku Python, który potrafiśrednia prędkość jazdy samochodem. Są to jednak różne drogi, na których występują prędkości (są one reprezentowane przez cyfry 0–9), plik może mieć dowolny numer drogi i dowolną prędkość.
Example1.txt
0 40km
1 30km
0 67km
2 45km
2 23km
Program, który chcę stworzyć z wykorzystaniem średniej dróg
average of 1 = 30
average of 0 = 35
plik może zawierać jednak wiele par, a drogi będą miały numery od 0 do 9 Oto co mam do tej pory:
def traffic_summary(filename):
in_file = open(filename)
lines = in_file.readlines()
in_file.close()
return lines
def calc_traffic_avg(lines):
# Find out how long the file is
total_lines = len(lines)
# For every file line, find the charity and the amount contributed
avg = 0 # Nums + however many / How ever many integers there are
road_nums = []
master = []
road_speeds = []
for i in range(1, total_lines): # Omits the title lines
current_line = lines[i].rstrip("n") #Removes the new line
current_line = current_line.split()
for j in range(len(current_line)):
current_word = current_line[j]
if "km" in current_word:
position = j
amount = int(current_word.rstrip("km"))
road_speeds.append(amount)
if not "km" in current_word:
road_nums.append(int(current_word))
print(road_nums, road_speeds)
Muszę wymyślić, jak uśrednić liczbę prędkości na drogach.
Odpowiedzi:
2 dla odpowiedzi № 1Musisz śledzić wszystkie prędkości dla każdej drogi, a nie tylko lista wszystkich prędkości i lista wszystkich dróg.
Jednym ze sposobów jest skorzystanie ze słownika: klucze to drogi, a wartości to lista lub zestaw * prędkości dla tej drogi. Możesz użyć collections.defaultdict(list)
(lub …(set)
), aby ułatwić tworzenie.
Ale musisz także wiedzieć, którą drogę ma prędkośćidzie z. Sposób, w jaki piszesz rzeczy, traktujesz każde słowo jako całkowicie niezależną rzecz, ignorując fakt, że występują w parach (i inne przydatne rzeczy, takie jak fakt, że w każdej linii jest zawsze dokładnie jedna para) , co oznacza, że nie masz możliwości dowiedzieć się, z którym razem.
Jeśli format pliku jest naprawdę zgodny z opisem, możesz to uczynić o wiele prostszym: zamiast zapętlania current_line
, skorzystaj z faktu, że current_line[0]
jest droga i current_line[1]
to prędkość. Lubię to:
road_speeds = collections.defaultdict(list)
# ...
# ... inside the loop
road, speed = current_line.split()
road = int(road)
speed = int(speed.rstrip("km"))
road_speeds[road].append(speed)
Teraz, kiedy skończysz wszystko, będziesz mieć słownik, który wygląda mniej więcej tak:
{0: [40, 67], 2: [45, 23], 1: [30]}
Jak więc uzyskać średnią prędkość dla każdej drogi?
for road, speeds in road_speeds.items():
average_speed = sum(speeds) / len(speeds)
print(road, average_speed)
Zauważ, że jeśli masz Python 3.4+, może być bardziej czytelny lub wyraźny w użyciu statistics.mean
zamiast dzielić sum
przez len
.
* Skąd wiesz, czy użyć zestawu, czy listy? Zasadniczo, jeśli ma sens koncepcyjny, aby traktować duplikaty inaczej lub rozważyć kolejność wpisów w znaczeniu, to masz listę; w przeciwnym razie masz zestaw. W takim przypadku, jeśli na tej samej drodze są dwie podróże o tej samej prędkości, prawdopodobnie nadal chcesz je uznać za odrębne, ponieważ DSM wskazał, więc lista prawdopodobnie ma tutaj większy sens.
1 dla odpowiedzi nr 2
collections.defaultdict i collections.Counter będzie użyteczne:
from collections import defaultdict,Counter
d = defaultdict(float)
count = Counter() # get count of all times the road appears in the file
with open("in.txt") as f:
for line in f:
rd, speed = line.rstrip().split()
d[rd] += float(speed.rstrip("km")) # sum km for each road/key
count.update(rd)
for k, v in d.items():
print("Road {} average = {}".format(k,v/count[k])) # divide sum by times road appears
Road 1 average = 30.0
Road 0 average = 53.5
Road 2 average = 34.0