如何有选择地附加列表?
How to append a list selectively?
我正在通过 RFID reader 接收消息。我想做的是删除重复项并仅在满足两个条件的情况下附加到列表中:
- 如果他们的 ID(在本例中为
epc
)是唯一的,并且 (完成)
datetime
是在 5 分钟间隔之后(所以我可以跟踪同一标签仍然被 RFID reader 每 5 分钟读取一次)
import paho.mqtt.client as mqtt
import json
testlist = []
def on_message(client, userdata, msg):
payloadjson = json.loads(msg.payload.decode('utf-8'))
line = payloadjson["value"].split(',')
epc = line[1]
datetime = payloadjson['datetime']
# datetime is in this string format '2016-04-06 03:21:17'
payload = {'datetime': datetime, 'epc': epc[11:35]}
# this if-statement satisfy condition 1
if payload not in testlist:
testlist.append(payload)
for each in teslist:
print (each)
test = mqtt.Client(protocol = mqtt.MQTTv31)
test.connect(host=_host, port=1883, keepalive=60, bind_address="")
test.on_connect = on_connect
test.on_message = on_message
test.loop_forever()
我怎样才能达到条件 2?
更新
对于我试图实现的目标不明确,我深表歉意
我想要的输出看起来像这样:
{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B
...
...
# 5 minutes later
{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B
{'datetime': 2016-04-06 03:26:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:26:18', 'epc': 00000002} # from Tag B
...
...
# Another 5 minutes later
{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B
{'datetime': 2016-04-06 03:26:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:26:18', 'epc': 00000002} # from Tag B
{'datetime': 2016-04-06 03:31:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:31:18', 'epc': 00000002} # from Tag B
...
...
这可能是一种更简单的方法:
class EPC(object):
def __init__(self, epc, date):
self.epc = epc
self.datetime = date
def __eq__(self, other):
difference = datetime.strptime(self.datetime, '%Y-%m-%d %H:%M:%S') - datetime.strptime(other.datetime, '%Y-%m-%d %H:%M:%S')
return self.epc == other.epc and timedelta(minutes=-5) < difference < timedelta(minutes=5)
def __ne__(self, other):
difference = datetime.strptime(self.datetime, '%Y-%m-%d %H:%M:%S') - datetime.strptime(other.datetime, '%Y-%m-%d %H:%M:%S')
return self.epc != other.epc or (self.epc == other.epc and (difference > timedelta(minutes=5) or difference < timedelta(minutes=-5)))
payload = EPC(date, epc[11:35])
if payload not in test_list:
test_list.append(payload)
我想知道 epc
值是否可以来回交替。也就是说,有没有可能先出现epc值'A',再出现epc值'B',再出现epc值'A'? (或者可能是 A、B、C 等?)
如果假设只有一个标签,那么只看最近的条目:
last_tag = testlist[-1]
last_dt = last_tag['datetime']
现在您可以将当前 datetime
与之前的值进行比较,看看它是否适合您的 window。
不过请注意,将日期时间代码放在 has 中实际上对您现有的代码不起作用,因为日期时间不断变化,因此 payload not in testlist
将始终为真,除非您获得两个 RFID在同一秒读取。
有几点可以解决您的问题:
- 为了 ID 的唯一性,您只需要检查
epc
字段,而不是整个 payload
对象,因为 payload
对象包含 datetime
。您可以使用 set
来存储所有看到的 ID。
- 为了检查时间,使用
datetime
和timedelta
对象比较时间
# -*- coding: utf-8 -*-
"""
06 Apr 2016
To answer
"""
# Import statements
# import paho.mqtt.client as mqtt
import json
import datetime as dt
testlist = []
seen_ids = set() # The set of seen IDs
five_minutes = dt.timedelta(minutes=5) # The five minutes differences
def on_message(client, userdata, msg):
payloadjson = json.loads(msg.payload.decode('utf-8'))
line = payloadjson["value"].split(',')
epc = line[1]
datetime = payloadjson['datetime']
# datetime is in this string format '2016-04-06 03:21:17'
# Convert the string into datetime object
datetime = dt.datetime.strptime(datetime, '%Y-%m-%d %H:%M:%S')
payload = {'datetime': datetime, 'epc': epc[11:35]}
# this if-statement satisfy condition 1
if payload['epc'] not in seen_ids: # Need to use another set
should_add = True # The flag whether to add
if len(testlist) > 0:
last_payload = testlist[-1]
diff = payload['datetime'] - last_payload['datetime']
if diff < five_minutes: # If the newer one is less than five minutes, do not add
should_add = False
if should_add:
seen_ids.add(payload['epc']) # Mark as seen
testlist.append(payload)
print ('Content of testlist now:')
for each in testlist:
print (each)
class Message(object):
def __init__(self, payload):
self.payload = payload
def main():
test_cases = []
for i in range(10):
payload = '{{"value":",{}","datetime":"2016-04-06 03:{:02d}:17"}}'.format('0'*34+str(i), i)
test_case = Message(payload)
test_cases.append(test_case)
for test_case in test_cases:
on_message(None, None, test_case)
if __name__ == '__main__':
main()
将打印:
Content of testlist now:
{'epc': u'000000000000000000000000', 'datetime': datetime.datetime(2016, 4, 6, 3, 0, 17)}
Content of testlist now:
{'epc': u'000000000000000000000000', 'datetime': datetime.datetime(2016, 4, 6, 3, 0, 17)}
{'epc': u'000000000000000000000005', 'datetime': datetime.datetime(2016, 4, 6, 3, 5, 17)}
你的问题有点不清楚。假设您想要更新测试列表,如果它是一个新的 epc,或者如果它自上次更新 epc 以来已经超过 5 分钟。 dict()
在这种情况下效果很好。使用标准库中的 datetime
模块计算日期或时间的差异。
import paho.mqtt.client as mqtt
import json
import datetime as dt
TIMELIMIT = dt.timedelta(minutes=5)
testlist = {} ## <<-- changed this to a dict()
def on_message(client, userdata, msg):
payloadjson = json.loads(msg.payload.decode('utf-8'))
line = payloadjson["value"].split(',')
epc = line[1]
# this converts the time stamp string to something python can
# use in date / time calculations
when = dt.datetime.strptime(payloadjson['datetime'], '%Y-%m-%d %H:%M:%S')
if epc not in testlist or when - testlist[epc] > TIMELIMIT:
testlist[epc] = when
for epc, when in teslist.items():
print (epc, when)
我正在通过 RFID reader 接收消息。我想做的是删除重复项并仅在满足两个条件的情况下附加到列表中:
- 如果他们的 ID(在本例中为
epc
)是唯一的,并且 (完成) datetime
是在 5 分钟间隔之后(所以我可以跟踪同一标签仍然被 RFID reader 每 5 分钟读取一次)import paho.mqtt.client as mqtt import json testlist = [] def on_message(client, userdata, msg): payloadjson = json.loads(msg.payload.decode('utf-8')) line = payloadjson["value"].split(',') epc = line[1] datetime = payloadjson['datetime'] # datetime is in this string format '2016-04-06 03:21:17' payload = {'datetime': datetime, 'epc': epc[11:35]} # this if-statement satisfy condition 1 if payload not in testlist: testlist.append(payload) for each in teslist: print (each) test = mqtt.Client(protocol = mqtt.MQTTv31) test.connect(host=_host, port=1883, keepalive=60, bind_address="") test.on_connect = on_connect test.on_message = on_message test.loop_forever()
我怎样才能达到条件 2?
更新
对于我试图实现的目标不明确,我深表歉意
我想要的输出看起来像这样:
{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B
...
...
# 5 minutes later
{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B
{'datetime': 2016-04-06 03:26:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:26:18', 'epc': 00000002} # from Tag B
...
...
# Another 5 minutes later
{'datetime': 2016-04-06 03:21:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:21:18', 'epc': 00000002} # from Tag B
{'datetime': 2016-04-06 03:26:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:26:18', 'epc': 00000002} # from Tag B
{'datetime': 2016-04-06 03:31:17', 'epc': 00000001} # from Tag A
{'datetime': 2016-04-06 03:31:18', 'epc': 00000002} # from Tag B
...
...
这可能是一种更简单的方法:
class EPC(object):
def __init__(self, epc, date):
self.epc = epc
self.datetime = date
def __eq__(self, other):
difference = datetime.strptime(self.datetime, '%Y-%m-%d %H:%M:%S') - datetime.strptime(other.datetime, '%Y-%m-%d %H:%M:%S')
return self.epc == other.epc and timedelta(minutes=-5) < difference < timedelta(minutes=5)
def __ne__(self, other):
difference = datetime.strptime(self.datetime, '%Y-%m-%d %H:%M:%S') - datetime.strptime(other.datetime, '%Y-%m-%d %H:%M:%S')
return self.epc != other.epc or (self.epc == other.epc and (difference > timedelta(minutes=5) or difference < timedelta(minutes=-5)))
payload = EPC(date, epc[11:35])
if payload not in test_list:
test_list.append(payload)
我想知道 epc
值是否可以来回交替。也就是说,有没有可能先出现epc值'A',再出现epc值'B',再出现epc值'A'? (或者可能是 A、B、C 等?)
如果假设只有一个标签,那么只看最近的条目:
last_tag = testlist[-1]
last_dt = last_tag['datetime']
现在您可以将当前 datetime
与之前的值进行比较,看看它是否适合您的 window。
不过请注意,将日期时间代码放在 has 中实际上对您现有的代码不起作用,因为日期时间不断变化,因此 payload not in testlist
将始终为真,除非您获得两个 RFID在同一秒读取。
有几点可以解决您的问题:
- 为了 ID 的唯一性,您只需要检查
epc
字段,而不是整个payload
对象,因为payload
对象包含datetime
。您可以使用set
来存储所有看到的 ID。 - 为了检查时间,使用
datetime
和timedelta
对象比较时间
# -*- coding: utf-8 -*-
"""
06 Apr 2016
To answer
"""
# Import statements
# import paho.mqtt.client as mqtt
import json
import datetime as dt
testlist = []
seen_ids = set() # The set of seen IDs
five_minutes = dt.timedelta(minutes=5) # The five minutes differences
def on_message(client, userdata, msg):
payloadjson = json.loads(msg.payload.decode('utf-8'))
line = payloadjson["value"].split(',')
epc = line[1]
datetime = payloadjson['datetime']
# datetime is in this string format '2016-04-06 03:21:17'
# Convert the string into datetime object
datetime = dt.datetime.strptime(datetime, '%Y-%m-%d %H:%M:%S')
payload = {'datetime': datetime, 'epc': epc[11:35]}
# this if-statement satisfy condition 1
if payload['epc'] not in seen_ids: # Need to use another set
should_add = True # The flag whether to add
if len(testlist) > 0:
last_payload = testlist[-1]
diff = payload['datetime'] - last_payload['datetime']
if diff < five_minutes: # If the newer one is less than five minutes, do not add
should_add = False
if should_add:
seen_ids.add(payload['epc']) # Mark as seen
testlist.append(payload)
print ('Content of testlist now:')
for each in testlist:
print (each)
class Message(object):
def __init__(self, payload):
self.payload = payload
def main():
test_cases = []
for i in range(10):
payload = '{{"value":",{}","datetime":"2016-04-06 03:{:02d}:17"}}'.format('0'*34+str(i), i)
test_case = Message(payload)
test_cases.append(test_case)
for test_case in test_cases:
on_message(None, None, test_case)
if __name__ == '__main__':
main()
将打印:
Content of testlist now: {'epc': u'000000000000000000000000', 'datetime': datetime.datetime(2016, 4, 6, 3, 0, 17)} Content of testlist now: {'epc': u'000000000000000000000000', 'datetime': datetime.datetime(2016, 4, 6, 3, 0, 17)} {'epc': u'000000000000000000000005', 'datetime': datetime.datetime(2016, 4, 6, 3, 5, 17)}
你的问题有点不清楚。假设您想要更新测试列表,如果它是一个新的 epc,或者如果它自上次更新 epc 以来已经超过 5 分钟。 dict()
在这种情况下效果很好。使用标准库中的 datetime
模块计算日期或时间的差异。
import paho.mqtt.client as mqtt
import json
import datetime as dt
TIMELIMIT = dt.timedelta(minutes=5)
testlist = {} ## <<-- changed this to a dict()
def on_message(client, userdata, msg):
payloadjson = json.loads(msg.payload.decode('utf-8'))
line = payloadjson["value"].split(',')
epc = line[1]
# this converts the time stamp string to something python can
# use in date / time calculations
when = dt.datetime.strptime(payloadjson['datetime'], '%Y-%m-%d %H:%M:%S')
if epc not in testlist or when - testlist[epc] > TIMELIMIT:
testlist[epc] = when
for epc, when in teslist.items():
print (epc, when)