Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
函数从python中的元组列表中删除重复项_Python_Function_Duplicates_Tuples - Fatal编程技术网

函数从python中的元组列表中删除重复项

函数从python中的元组列表中删除重复项,python,function,duplicates,tuples,Python,Function,Duplicates,Tuples,在函数sqlPull()中,我每5秒从MySQL数据库中提取最近的5个条目。在第二个函数dupCatch()中,我试图删除与n相比,在n+1sql pull中可能存在的重复项。我只想保存唯一的元组列表,但现在该函数每5秒打印相同的元组列表5次 在英语中,我试图对dupCatch()执行的操作是从sqlPull()获取数据,初始化并清空列表,并对变量数据中的所有元组说,如果该元组不在空列表中,则将其添加到newData变量,如果不在空列表中,则将lastPull设置为非唯一元组 显然,我的函数是错

在函数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