函数从python中的元组列表中删除重复项
在函数sqlPull()中,我每5秒从MySQL数据库中提取最近的5个条目。在第二个函数dupCatch()中,我试图删除与n相比,在n+1sql pull中可能存在的重复项。我只想保存唯一的元组列表,但现在该函数每5秒打印相同的元组列表5次 在英语中,我试图对dupCatch()执行的操作是从sqlPull()获取数据,初始化并清空列表,并对变量数据中的所有元组说,如果该元组不在空列表中,则将其添加到newData变量,如果不在空列表中,则将lastPull设置为非唯一元组 显然,我的函数是错误的,但我不知道如何修复它函数从python中的元组列表中删除重复项,python,function,duplicates,tuples,Python,Function,Duplicates,Tuples,在函数sqlPull()中,我每5秒从MySQL数据库中提取最近的5个条目。在第二个函数dupCatch()中,我试图删除与n相比,在n+1sql pull中可能存在的重复项。我只想保存唯一的元组列表,但现在该函数每5秒打印相同的元组列表5次 在英语中,我试图对dupCatch()执行的操作是从sqlPull()获取数据,初始化并清空列表,并对变量数据中的所有元组说,如果该元组不在空列表中,则将其添加到newData变量,如果不在空列表中,则将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')]
试试这个:
def dupCatch():
data = sqlPull()
lastPull = []
for x in data:
if x not in lastPull:
print(x)
lastPull.append(x)
问题在于,
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)
假设你只是想过滤掉相邻的重复,而不是以前见过的重复 首先,第一次在
lastPull
中找到元组时,要设置lastPull=data
。这意味着所有后续元组将自动位于lastPull
中
同时,每次通过循环都要设置lastPull
或newData
。因此,其中一种情况即将发生:
- 如果所有元组都是新元组,则将设置
(重复)而不更新newData
lastPull
- 如果第一个元组是新的,但至少有一个元组是重复的,则将设置
,并更新newData
lastPull
- 如果第一个元组是重复元组,则只更新
lastPull
any
或all
,或者在其中一个条件中添加break
,并在for
的else
子句中添加相反的内容,但我真的不确定您想在这里做什么
同时,您的代码每次通过循环都会打印新数据。因此,对于每个元组,您将打印所有元组。如上所述,如果第一个元组是新元组,则始终为新元组,否则为前一个元组。再说一遍,这不可能是你想要的,但我不确定你想要什么。也许您希望在循环外打印新数据,而不是每次都通过
最重要的是,你说你想在newData
列表中添加一些东西,但是在你的代码中你只是在反复替换变量。要向列表中添加内容,您需要调用append
。(或扩展
,如果您有一个新事物列表要一次性添加。)与其尝试了解您的代码试图做什么并修复它,不如回到您的英文描述:
在英语中,我试图对dupCatch()执行的操作是从sqlPull()获取数据,初始化并清空列表,并对变量数据中的所有元组说,如果该元组不在空列表中,则将其添加到newData变量,如果不在空列表中,则将lastPull设置为非唯一元组
因此:
或者,更简洁地说:
seen = set()
def dupCatch():
data = sqlPull()
newData = [row for row in data if row not in seen]
seen.update(newData)
print new_data
不管怎样,这里的诀窍是我们有一套记录我们见过的每一行的记录。因此,对于每一个新行,如果它在该集合中,我们已经看到它,并且可以忽略它;否则,我们不能忽略它,并将其添加到集合中以供以后使用
第二个版本只是通过一次过滤所有5行,然后用所有新行一次更新集合,而不是逐行进行,从而简化了工作
看到的
必须是全局的原因是全局永远存在于函数的所有运行中,因此我们可以使用它来跟踪我们见过的每一行;如果我们将它设置为函数的本地,那么每次都是新的,因此我们只会跟踪当前批处理中看到的行,这不是很有用
总的来说,全球化是不好的。然而,持久缓存之类的东西是“一般”规则的例外。它们的全部意义在于它们不是本地的。如果您心中有一个有意义的对象模型,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
请参阅和接下来的几个教程部分、文档,并了解最后一个版本的功能。但是对于新手来说,您可能希望坚持使用第二个版本。您是否试图过滤掉以前看到的行的重复,或者只是最近的行?以前看到的行我以前从未使用过类-这肯定会有助于学习我遇到此错误“'SqlPuller'对象没有属性'connection'”我也不确定所有的self都是什么意思。@Barnaby:关于类的知识是值得学习的,但是如果不给你一个完整的教程,很难解释“所有self都是什么意思”,所以……也许可以阅读官方Python教程中关于?可能还有更好的,但我不知道。@Barnaby:与此同时,你看到的错误看起来像是一个非常简单的打字错误,一个额外的
自我。我编辑了他的答案来解决这个问题。但是我应该指出,这个代码实际上并不能解决您的问题,因为他每次都在替换self.last_pull,这违背了让它持久化的全部目的。@abarnert谢谢
for row in unique_everseen(chain.from_iterable(iter(sqlPull, None))):
print row