在函数sqlPull()中,我每隔5秒从MySQL数据库中提取最近的5个条目。在第二个函数dupCatch()中,我试图删除与n相比在n + 1 SQL拉中的重复项。我想只保存唯一的元组列表,但是现在该函数每5秒打印5次相同的元组列表。
在英语中我试图用dupCatch()做的是从sqlPull()中获取数据,初始化和清空列表,并说明变量数据中的所有元组,如果该元组不在空列表中,则添加如果没有,则将lastPull设置为非唯一元组。
显然,我的功能是错误的,但我不确定如何解决它。
import mysql.connector
import datetime
import requests
from operator import itemgetter
import time
run = True
def sqlPull():
connection = mysql.connector.connect(user='XXX', password='XXX', host='XXXX', database='MeshliumDB')
cursor = connection.cursor()
cursor.execute("SELECT TimeStamp, MAC, RSSI FROM wifiscan ORDER BY TimeStamp DESC LIMIT 5;")
data = cursor.fetchall()
connection.close()
time.sleep(5)
return data
def dupCatch():
data = sqlPull()
lastPull = []
for (TimeStamp, MAC, RSSI) in data:
if (TimeStamp, MAC, RSSI) not in lastPull:
newData = data
else:
lastPull = data
print newData
while run == True:
dupCatch()
这就是我现在得到的输出:
[(datetime.datetime(2013, 11, 14, 20, 28, 54), u'E0:CB:1D:36:EE:9D', u' 20'), (datetime.datetime(2013, 11, 14, 20, 28, 53), u'00:1E:8F:75:82:35', u' 21'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'00:1E:4C:03:C0:66', u' 26'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33')]
[(datetime.datetime(2013, 11, 14, 20, 28, 54), u'E0:CB:1D:36:EE:9D', u' 20'), (datetime.datetime(2013, 11, 14, 20, 28, 53), u'00:1E:8F:75:82:35', u' 21'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'00:1E:4C:03:C0:66', u' 26'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33')]
[(datetime.datetime(2013, 11, 14, 20, 28, 54), u'E0:CB:1D:36:EE:9D', u' 20'), (datetime.datetime(2013, 11, 14, 20, 28, 53), u'00:1E:8F:75:82:35', u' 21'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'00:1E:4C:03:C0:66', u' 26'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33')]
[(datetime.datetime(2013, 11, 14, 20, 28, 54), u'E0:CB:1D:36:EE:9D', u' 20'), (datetime.datetime(2013, 11, 14, 20, 28, 53), u'00:1E:8F:75:82:35', u' 21'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'00:1E:4C:03:C0:66', u' 26'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33')]
[(datetime.datetime(2013, 11, 14, 20, 28, 54), u'E0:CB:1D:36:EE:9D', u' 20'), (datetime.datetime(2013, 11, 14, 20, 28, 53), u'00:1E:8F:75:82:35', u' 21'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'00:1E:4C:03:C0:66', u' 26'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33')]
[(datetime.datetime(2013, 11, 14, 20, 28, 54), u'E0:CB:1D:36:EE:9D', u' 20'), (datetime.datetime(2013, 11, 14, 20, 28, 53), u'00:1E:8F:75:82:35', u' 21'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'00:1E:4C:03:C0:66', u' 26'), (datetime.datetime(2013, 11, 14, 20, 28, 52), u'78:E4:00:0C:50:DF', u' 33')]
答案 0 :(得分:1)
假设你只是试图过滤掉相邻的重复,而不是重复的重复......
首先,当您第一次找到lastPull
中的元组时,您将设置lastPull = data
。这意味着所有后续元组将自动位于lastPull
。
同时,您每次都要设置lastPull
或newData
。因此,其中一个将会发生:
newData
(重复)而不是更新lastPull
。newData
并更新lastPull
。lastPull
。这不是你想要的逻辑。我想您想要使用any
或all
,或者将break
置于其中一个条件中,并将else
条款放在for
子句中但是,我不确定你在这里要做什么。
同时,您的代码每次循环都会print newData
。因此,对于每个元组,您将打印所有元组。如上所述,如果第一个元组是新元组,那么它将始终是新元组,否则将是之前的元组。同样,这可能不是你想要的,但我不确定你做什么想要什么。也许你想在循环之外print newData
,而不是每次都通过?
最重要的是,你说你想添加的东西到newData
列表,但在你的代码中你只是反复替换变量。要将内容添加到列表中,您需要在其上调用append
。 (或者extend
,如果你有一个新的东西列表可以一次性添加。)
答案 1 :(得分:1)
让我们回到你的英文描述,而不是试图找出你的代码试图做什么并修复它,让我们回到你的英文描述:
在英语中我试图用dupCatch()做的是从sqlPull()中获取数据,初始化和清空列表,并说明变量数据中的所有元组,如果该元组不在空列表中,则添加如果没有,则将lastPull设置为非唯一元组。
所以:
seen = set()
def dupCatch():
data = sqlPull()
new_data = []
for (TimeStamp, MAC, RSSI) in data:
if (TimeStamp, MAC, RSSI) not in seen:
seen.add((TimeStamp, MAC, RSSI))
new_data.append((TimeStamp, MAC, RSSI))
print new_data
或者,更简洁:
seen = set()
def dupCatch():
data = sqlPull()
newData = [row for row in data if row not in seen]
seen.update(newData)
print new_data
无论哪种方式,这里的诀窍是我们有一个跟踪我们所见过的每一行的集合。所以,对于每一个新行,如果它在那个集合中,我们已经看到它并且可以忽略它;否则,我们不得忽略它,并将其添加到集合中以供日后使用。
第二个版本只是通过一次过滤所有5行来简化事情,然后update
一次性使用所有新行,而不是逐行过滤。
seen
必须是全局的原因是全局在函数的所有运行中永远存在,所以我们可以用它来跟踪我们见过的每一行;如果我们把它放在函数的本地,那么每次它都是新的,所以我们只跟踪我们在当前批次中看到的行,这不是很有用。
一般来说,全局变量很糟糕。但是,像持久性缓存这样的东西是“一般”规则的例外。他们的全部意义在于他们不本地。如果你有一个有意义的对象模型,那么seen
作为一个方法dupCatch
是一个方法而不是一个全局方面的成员会好得多。如果你有充分的理由将函数定义为另一个函数中的闭包,seen
作为闭包的一部分会更好。等等。但除此之外,全球化是最好的选择。
如果您重新组织了一些代码,可以使这更简单:
def pull():
while True:
for row in sqlPull():
yield row
for row in unique_everseen(pull()):
print row
......甚至:
for row in unique_everseen(chain.from_iterable(iter(sqlPull, None))):
print row
请参阅Iterators以及接下来的几个教程部分,itertools
文档和David M. Beazley's presentations,以了解上一版本的功能。但是对于新手来说,你可能想要坚持使用第二个版本。
答案 2 :(得分:0)
试试这个:
def dupCatch():
data = sqlPull()
lastPull = []
for x in data:
if x not in lastPull:
print(x)
lastPull.append(x)
答案 3 :(得分:0)
问题是lastPull
是一个局部变量,因此每次都设置为[]
,并且不会在函数调用之间保持不变。对于你想要做的事情,你应该使用一个类并存储最后一个拉:
import mysql.connector
import datetime
import requests
import time
class SqlPuller(object):
def __init__(self):
self.last_pull = set()
def pull(self):
connection = mysql.connector.connect(user='XXX', password='XXX',
host='XXXX', database='MeshliumDB')
cursor = connection.cursor()
cursor.execute("SELECT TimeStamp, MAC, RSSI FROM wifiscan ORDER BY TimeStamp DESC LIMIT 5;")
data = cursor.fetchall()
connection.close()
return data
def pull_new(self):
new_data = []
data = self.pull()
for item in data:
if item not in self.last_pull:
new_data.append(item)
self.last_pull = set(data)
return new_data
if __name__ == "__main__":
sql_puller = SqlPuller()
while True:
for item in sql_puller.pull():
print(item)
time.sleep(5)