![](/img/trans.png)
[英]How do I search through a list of dictionaries in python when I want to find multiple dictionaries which have multipe same values for multiple keys?
[英]i have multiple dictionaries in a python list. i want to find what they share in values & then compare them, while looping through a list of them
好的,這是一個示例數據集:
returntime= '9:00'
data1 = {Name:'jim', cardriven: '20123', time:'7:30'}
data1 = {Name:'bob', cardriven: '20123', time:'10:30'}
data1 = {Name:'jim', cardriven: '201111', time:'8:30'}
data1 = {Name:'bob', cardriven: '201314', time:'9:30'}
我的問題是我需要能夠遍歷這些字典並找到他們倆都駕駛過的汽車然后比較他們駕駛他們的時間以查看誰在最接近 9:00 時還車
我已經嘗試了許多循環和創建列表等...但我知道必須有一種簡單的方式來說...
對於 [data1, data2 ....] 誰返回了最接近時間的汽車...這是該記錄中的信息。
提前謝謝
也許您可以嘗試僅使用 1 個dict
,其中字典中的每個條目都是另一個字典,其鍵可能是驅動程序的名稱或 ID 代碼。
然后您可以遍歷該字典並找出哪些字典條目駕駛了同一輛車。
這是我的意思的簡化示例
returntime= '9:00'
data1 = {'Name':'jim', 'cardriven': '20123', 'time': "7:30"}
data2 = {'Name':'bob', 'cardriven': '20123', 'time': "10:30"}
data3 = {'Name':'jim', 'cardriven': '201111', 'time': "8:30"}
dict = {}
dict[0] = data1
dict[1] = data2
dict[2] = data3
for i in range(len(dict)):
if dict[i]["cardriven"] == '20123':
print(dict[i]["Name"])
Output:
jim
bob
還有一個專業提示:您可以將時間作為日期時間 object 輸入到字典中,這將極大地幫助您比較時間。
這將遍歷您提供的數據並將汽車放入字典中,該字典將跟蹤最接近目標的汽車。
import datetime
returntime = "09:00"
data = [
dict(name="Jim", cardriven="20123", time="7:30"),
dict(name="Bob", cardriven="20123", time="10:30"),
dict(name="Jim", cardriven="201111", time="8:30"),
dict(name="Bob", cardriven="201314", time="9:30"),
]
def parsedelta(s):
t = datetime.datetime.strptime(s, "%M:%S")
return datetime.timedelta(minutes=t.minute, seconds=t.second)
deltareturn = parsedelta(returntime)
def diffreturn(s):
return abs(deltareturn.seconds - parsedelta(s).seconds)
cars = {}
for datum in data:
car = datum["cardriven"]
if car not in cars:
cars[car] = datum
continue
if diffreturn(datum["time"]) < diffreturn(cars[car]["time"]):
cars[car] = datum
print(cars)
由於我們想找到他們都開過的汽車,我們可以創建一個字典,其中每個鍵是所駕駛的汽車,每個值是名稱-時間對的列表以及都開過的汽車的列表。然后比較時間看看誰最接近returntime
歸還它。
from datetime import datetime
temp = {}
both_drove = []
for data in [data1, data2, data3, data4]:
if data['cardriven'] in temp:
temp[data['cardriven']].append((data['Name'], data['time']))
both_drove.append(data['cardriven'])
else:
temp[data['cardriven']] = [(data['Name'], data['time'])]
returntime = datetime.strptime(returntime, '%H:%M')
for car in both_drove:
p1, p2 = temp[car]
if abs(datetime.strptime(p1[1], '%H:%M') - returntime) > abs(datetime.strptime(p2[1], '%H:%M') - returntime):
print(p2)
else:
print(p1)
Output:
('jim', '7:30')
NB 目前尚不清楚哪個更接近returntime
, 10:30
或7:30
。
測試數據對於這個問題來說有點時髦。 您基本上是在尋找一種 groupby 和 sort 方法,但是您的測試數據中的 3 個組中有 2 個只有一個條目。 此外,對於汽車20123
,時間與返回時間的距離相等(我在下面的答案中為delta_min
)。 在這種情況下,下面的sort_values
步驟不會影響順序。 如果您知道應如何對等距離條目進行排名,那么您可以進行下一步。
盡管如此,我認為最好的做法是將其轉換為 pandas 日期幀並創建一個管道。 對於這個數據
data1 = {"Name":'jim', "cardriven": '20123', "time":'7:30'}
data2 = {"Name":'bob', "cardriven": '20123', "time":'10:30'}
data3 = {"Name":'jim', "cardriven": '201111', "time":'8:30'}
data4 = {"Name":'bob', "cardriven": '201314', "time":'9:30'}
我們可以設計一個管道,使用ljmc的答案中提出的優秀parsedelta
function 的修改版本。
import datetime
import pandas as pd
data = pd.DataFrame([data1, data2, data3, data4])
# Name cardriven time
# 0 jim 20123 7:30
# 1 bob 20123 10:30
# 2 jim 201111 8:30
# 3 bob 201314 9:30
def timedelta(time):
t = datetime.datetime.strptime(time, "%H:%M")
return datetime.timedelta(hours=t.hour, minutes=t.minute).seconds / 60
returntime= '9:00'
latest_entries = (
data
.assign(delta_min=lambda d: abs(d["time"].apply(timedelta) - timedelta(returntime)))
.sort_values("delta_min")
.drop("delta_min", axis = 1) # comment this out if you want the minute difference
.drop_duplicates(subset="cardriven")
)
print(latest_entries)
這給了我們
Name cardriven time
2 jim 201111 8:30
0 jim 20123 7:30
3 bob 201314 9:30
更進一步,我們可以通過將timedelta
function 直接作為sort_values
步驟中的key
參數傳遞來簡化管道。 我們還拆分了 timedelta function。
def _timedelta(tm):
t = datetime.datetime.strptime(tm, "%H:%M")
return datetime.timedelta(hours=t.hour, minutes=t.minute).seconds / 60
def timedelta(time, rtrn_time):
return abs(_timedelta(time) - _timedelta(rtrn_time))
returntime= '9:00'
latest_entries = (
data
.sort_values("time", key=lambda d: d.apply(timedelta, rtrn_time=returntime))
.drop_duplicates(subset="cardriven")
)
print(latest_entries)
Name cardriven time
2 jim 201111 8:30
0 jim 20123 7:30
3 bob 201314 9:30
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.