Programing

목록에서 어떤 값과 동일한 속성을 가진 객체를 찾습니다 (조건에 부합)

lottogame 2020. 5. 22. 08:04
반응형

목록에서 어떤 값과 동일한 속성을 가진 객체를 찾습니다 (조건에 부합)


개체 목록이 있습니다. 이 목록에서 속성 (또는 메소드 결과에 관계없이)과 동일한 객체를 찾고 싶습니다 value.

그것을 찾는 가장 좋은 방법은 무엇입니까?

테스트 사례는 다음과 같습니다.

  class Test:
      def __init__(self, value):
          self.value = value

  import random

  value = 5

  test_list = [Test(random.randint(0,100)) for x in range(1000)]

  # that I would do in Pascal, I don't believe isn't anywhere near 'Pythonic'
  for x in test_list:
      if x.value == value:
          print "i found it!"
          break

나는 발전기를 사용한다고 생각 reduce()하지만 여전히 목록을 반복 할 것이기 때문에 아무런 차이가 없습니다.

추신 : 방정식 value은 단지 예입니다. 물론 우리는 어떤 조건에 맞는 요소를 원합니다.


next((x for x in test_list if x.value == value), None)

조건과 일치하는 목록에서 첫 번째 항목을 가져오고 일치하는 None항목이 없으면 반환 합니다. 내가 선호하는 단일 표현 양식입니다.

하나,

for x in test_list:
    if x.value == value:
        print "i found it!"
        break

순진한 루프 브레이크 버전은 완벽하게 Pythonic입니다. 간결하고 명확하며 효율적입니다. 원 라이너의 동작과 일치 시키려면 :

for x in test_list:
    if x.value == value:
        print "i found it!"
        break
else:
    x = None

루프를 벗어나지 않으면 할당 None됩니다 .xbreak


그것은 단지 완료를 위해 언급되지 않았기 때문에. 필터링 된 요소를 필터링하는 좋은 ol '필터.

기능적 프로그래밍 ftw.

####### Set Up #######
class X:

    def __init__(self, val):
        self.val = val

elem = 5

my_unfiltered_list = [X(1), X(2), X(3), X(4), X(5), X(5), X(6)]

####### Set Up #######

### Filter one liner ### filter(lambda x: condition(x), some_list)
my_filter_iter = filter(lambda x: x.val == elem, my_unfiltered_list)
### Returns a flippin' iterator at least in Python 3.5 and that's what I'm on

print(next(my_filter_iter).val)
print(next(my_filter_iter).val)
print(next(my_filter_iter).val)

### [1, 2, 3, 4, 5, 5, 6] Will Return: ###
# 5
# 5
# Traceback (most recent call last):
#   File "C:\Users\mousavin\workspace\Scripts\test.py", line 22, in <module>
#     print(next(my_filter_iter).value)
# StopIteration


# You can do that None stuff or whatever at this point, if you don't like exceptions.

나는 일반적으로 파이썬 목록에서 이해력이 선호되거나 적어도 그것이 읽은 것임을 알고 있지만 문제가 정직하지는 않습니다. 물론 파이썬은 FP 언어는 아니지만 Map / Reduce / Filter는 완벽하게 읽을 수 있으며 함수형 프로그래밍의 표준 사용 사례 중 가장 표준입니다.

그래서 당신은 간다. 당신의 기능적 프로그래밍을 아십시오.

필터 조건 목록

이보다 더 쉬울 수는 없습니다.

next(filter(lambda x: x.val == value,  my_unfiltered_list)) # Optionally: next(..., None) or some other default value to prevent Exceptions

I just ran into a similar problem and devised a small optimization for the case where no object in the list meets the requirement.(for my use-case this resulted in major performance improvement):

Along with the list test_list, I keep an additional set test_value_set which consists of values of the list that I need to filter on. So here the else part of agf's solution becomes very-fast.


You could also implement rich comparison via __eq__ method for your Test class and use in operator. Not sure if this is the best stand-alone way, but in case if you need to compare Test instances based on value somewhere else, this could be useful.

class Test:
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
        """To implement 'in' operator"""
        # Comparing with int (assuming "value" is int)
        if isinstance(other, int):
            return self.value == other
        # Comparing with another Test object
        elif isinstance(other, Test):
            return self.value == other.value

import random

value = 5

test_list = [Test(random.randint(0,100)) for x in range(1000)]

if value in test_list:
    print "i found it"

For below code, xGen is an anonomous generator expression, yFilt is a filter object. Note that for xGen the additional None parameter is returned rather than throwing StopIteration when the list is exhausted.

arr =((10,0), (11,1), (12,2), (13,2), (14,3))

value = 2
xGen = (x for x in arr if x[1] == value)
yFilt = filter(lambda x: x[1] == value, arr)
print(type(xGen))
print(type(yFilt))

for i in range(1,4):
    print('xGen: pass=',i,' result=',next(xGen,None))
    print('yFilt: pass=',i,' result=',next(yFilt))

Output:

<class 'generator'>
<class 'filter'>
xGen: pass= 1  result= (12, 2)
yFilt: pass= 1  result= (12, 2)
xGen: pass= 2  result= (13, 2)
yFilt: pass= 2  result= (13, 2)
xGen: pass= 3  result= None
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    print('yFilt: pass=',i,' result=',next(yFilt))
StopIteration

You could do something like this

dict = [{
   "id": 1,
   "name": "Doom Hammer"
 },
 {
    "id": 2,
    "name": "Rings ov Saturn"
 }
]

for x in dict:
  if x["id"] == 2:
    print(x["name"])

Thats what i use to find the objects in a long array of objects.

참고URL : https://stackoverflow.com/questions/7125467/find-object-in-list-that-has-attribute-equal-to-some-value-that-meets-any-condi

반응형