简体   繁体   English

列表中的单个元素

[英]single element in a list

I am fairly new to python and I came upon this code to find a single element in a list 我是python的新手,我发现这个代码在列表中找到一个元素

Here is the code: 这是代码:

def single_number(arr):
    ones, twos = 0, 0
    for x in arr:
        ones, twos = (ones ^ x) & ~twos, (ones & x) | (twos & ~x)
    assert twos == 0
    return ones
arr1 = [5, 3, 4, 3, 5, 5, 3]
print(single_number(arr1))

I just can't seem to understand what the line is doing 我似乎无法理解线路在做什么

ones, twos = (ones ^ x) & ~twos, (ones & x) | (twos & ~x)
assert twos==0

The purpose of that line is to implement an operation that returns the original value if applied three times with the input, and retains the input if applied once. 该行的目的是实现一个操作,如果输入应用了三次,则返回原始值,如果应用一次,则保留输入。

It's easier to understand if we wanted to pick a single value from an array containing pairs instead of triples. 如果我们想从包含对而不是三元组的数组中选择单个值,则更容易理解。 Then we could just do... 那我们就可以......

ones = ones ^ x

... because y ^ x ^ x == y. ...因为y ^ x ^ x == y。 So all the pairs cancel out and you're left with the single value. 所以所有对都取消了,你留下了单值。

As others have commented, the three-item case is a pretty nasty obscure hack that should only be used when performance is essential and the problem is very specific. 正如其他人评论的那样,三项案例是一个非常讨厌的模糊黑客,只有在性能至关重要且问题非常具体时才能使用。

I think the assert is just an attempt to confirm that the precondition was met, ie all numbers are triples except for one. 我认为断言只是试图确认满足前提条件,即所有数字都是三元组,除了一条。 It's not fail-safe. 这不是故障安全的。

You would not want to do it like this, unless you are really memory-space limited - and even then, you probably should not use it. 你不会想这样做,除非你真的受到内存空间的限制 - 即便如此,你可能也不应该使用它。

This is some kind of bit shifting / bit ops "magic" that is 这是某种位移/位操作“神奇”

  • not intuitive 不直观
  • dangerous to fiddle with 危险的小提琴
  • bad to maintain 不好维护
  • difficult to understand 很难理解

Counter works in O(n) - thats about the best you can do to check all elements in a list - it just takes some more constant time (to setup the Counter object) and some space (to maintain inner dict) over this bit-shift thingy you found. 计数器在O(n)中工作 - 这就是你可以做的最好的方法来检查列表中的所有元素 - 它只需要一些更恒定的时间(设置Counter对象)和一些空间(以维持内部字典) -你找到了转移的东西。

def getSingle(arr):
    from collections import Counter
    c = Counter(arr)

    return c.most_common()[-1]  # return the least common one -> (key,amounts) tuple

arr1 = [5, 3, 4, 3, 5, 5, 3]

counter = getSingle(arr1)

print (f"{counter[0]} occured {counter[1]} time(s)")

Output: 输出:

4 occured 1 time(s)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM