목록에서 요소 찾기 및 바꾸기


273

목록을 검색하고 한 요소의 모든 항목을 다른 요소로 바꿔야합니다. 지금까지 코드를 시도했지만 아무데도 도움이되지 않습니다.이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

예를 들어, 내 목록에 다음 정수가 있다고 가정하십시오.

>>> a = [1,2,3,4,5,1,2,3,4,5,1]

숫자 1의 모든 항목을 값 10으로 바꿔야하므로 필요한 출력이

>>> a = [10, 2, 3, 4, 5, 10, 2, 3, 4, 5, 10]

따라서 내 목표는 숫자 1의 모든 인스턴스를 숫자 10으로 바꾸는 것입니다.


11
그건 그렇고?
outis

답변:


250
>>> a= [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1]
>>> for n, i in enumerate(a):
...   if i == 1:
...      a[n] = 10
...
>>> a
[10, 2, 3, 4, 5, 10, 2, 3, 4, 5, 10]

15
이것은 나쁘고 비 파이썬적인 해결책입니다. 목록 이해를 고려하십시오.
AdHominem

203
매우 파이썬이 아닌 솔루션이라면 괜찮습니다. 목록 이해를 고려하십시오.
Jean-François Corbett

아래 @outis에 의해 수행되는 것과 같은 목록 이해를 고려하십시오!
amc

6
목록 이해력보다 성능이 좋지 않습니까? 새 목록을 생성하는 대신 전체 업데이트를 수행합니다.
neverendingqs

@neverendingqs : 아니요. 통역사 오버 헤드가 작업을 지배하며 이해력이 적습니다. 이해는 특히 대체 조건을 통과하는 요소의 비율이 높을수록 약간 더 잘 수행됩니다. 일부 타이밍 유무 : ideone.com/ZrCy6z이
user2357112 모니카 지원

517

목록 이해삼항 연산자를 사용해보십시오 .

>>> a=[1,2,3,1,3,2,1,1]
>>> [4 if x==1 else x for x in a]
[4, 2, 3, 4, 3, 2, 4, 4]

9
그러나 이것이 a옳은 것은 아니지만 ? 나는 영업 이익이 원하는 생각 a변경
DULA

10
당신은 할 수 @Dula = [4 X 경우 다른 == 1 X X에 대해,이 효과는 것
Alekhya Vemavarapu

@Dula : a변경 여부에 대한 질문은 모호 하지만, Alekhya가 보여주는 것처럼 목록 이해를 사용할 때 두 경우 모두를 처리하는 것은 쉽지 않습니다.
outis

34
변경하고 싶다면 변경 a해야합니다 a[:] = [4 if x==1 else x for x in a](전체 목록 조각 참고). 그냥 이렇게하면 a =새 목록이 생성됩니다 a다른과 id()원래의 (정체성)
Chris_Rands

39

목록 이해가 잘 작동하고 열거를 통해 반복하면 메모리가 절약 될 수 있습니다 (b / c 작업이 본질적으로 수행되고 있음).

기능적 프로그래밍도 있습니다. 지도 사용법을 참조하십시오 .

>>> a = [1,2,3,2,3,4,3,5,6,6,5,4,5,4,3,4,3,2,1]
>>> map(lambda x: x if x != 4 else 'sss', a)
[1, 2, 3, 2, 3, 'sss', 3, 5, 6, 6, 5, 'sss', 5, 'sss', 3, 'sss', 3, 2, 1]

17
+1. 너무 나쁜 lambdamapunpythonic 간주됩니다.
outis

4
람다 또는 맵이 본질적으로 비 유사성인지 확실하지 않지만 목록 이해가 두 가지를 함께 사용하는 것보다 깨끗하고 읽기 쉽다는 데 동의합니다.
damzam

7
나는 그것들을 비유 론적이라고 생각하지 않지만 Guido van Rossum ( artima.com/weblogs/viewpost.jsp?thread=98196 )을 포함하여 많은 사람들이 있습니다. 그것은 종파적인 것 중 하나입니다.
outis

35

대체 할 값이 여러 개인 경우 사전을 사용할 수도 있습니다.

a = [1, 2, 3, 4, 1, 5, 3, 2, 6, 1, 1]
dic = {1:10, 2:20, 3:'foo'}

print([dic.get(n, n) for n in a])

> [10, 20, 'foo', 4, 10, 5, 'foo', 20, 6, 10, 10]

1
에서 n찾을 수 없으면 오류가 발생 하지 dic않습니까?
Neil A.

3
@ user2914540 답을 조금 개선하여 n찾을 수없는 경우 작동합니다 . 나는 당신이 상관하지 않기를 바랍니다. 귀하의 try/except솔루션이 좋지 않았습니다.
jrjc

네, 더 좋습니다.
roipoussiere

1
전체 교체를위한 @jrjc @roipoussiere try-except는 최소 50 % 더 빠릅니다! 이 답변을
lifebalance

4
if n in dic.keys()성능이 좋지 않습니다. 사용 if n in dic하거나 dic.get(n,n)(기본값)
장 - 프랑수아 파브르

12
>>> a=[1,2,3,4,5,1,2,3,4,5,1]
>>> item_to_replace = 1
>>> replacement_value = 6
>>> indices_to_replace = [i for i,x in enumerate(a) if x==item_to_replace]
>>> indices_to_replace
[0, 5, 10]
>>> for i in indices_to_replace:
...     a[i] = replacement_value
... 
>>> a
[6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6]
>>> 

중간 빠르지 만 매우 합리적인 방법입니다. 내 답변의 타이밍을 참조하십시오.
dawg

10
a = [1,2,3,4,5,1,2,3,4,5,1,12]
for i in range (len(a)):
    if a[i]==2:
        a[i]=123

for 및 or while 루프를 사용할 수 있습니다. 그러나 내장 Enumerate 함수를 알고 있다면 Enumerate를 사용하는 것이 좋습니다. 1


1
목록 항목에 대해보다 복잡한 작업을 수행해야하는 경우이 작업을 수행 할 수있는 유일한 방법입니다. 예를 들어, 각 목록 항목이 긴 문자열 인 경우 검색 및 교체가 필요합니다.
not2qubit

8

모두 쉽게 교체하기 110a = [1,2,3,4,5,1,2,3,4,5,1]'봐, 엄마, 아니 IF를 또는 FORS를!'하나 다음과 같은 한 줄 람다 + 맵의 조합을 사용할 수 있으며, :

# This substitutes all '1' with '10' in list 'a' and places result in list 'c':

c = list(map(lambda b: b.replace("1","10"), a))


가장 느린 방법. 당신은 lambda모든 목록 요소에서 ...를 호출하고 있습니다
dawg

4

다음은 Python 2.x에서 매우 직접적인 방법입니다.

 a = [1,2,3,4,5,1,2,3,4,5,1]        #Replacing every 1 with 10
 for i in xrange(len(a)):
   if a[i] == 1:
     a[i] = 10  
 print a

이 방법이 작동합니다. 의견을 환영합니다. 그것이 도움이되기를 바랍니다 :)

또한 outisdamzam 솔루션의 작동 방식을 이해하십시오 . 리스트 압축과 람다 기능은 유용한 도구입니다.


3

나는 이것이 매우 오래된 질문이라는 것을 알고 있으며 그것을 할 수있는 많은 방법이 있습니다. 내가 찾은 가장 간단한 것은 numpy패키지를 사용하는 것 입니다.

import numpy

arr = numpy.asarray([1, 6, 1, 9, 8])
arr[ arr == 8 ] = 0 # change all occurrences of 8 by 0
print(arr)

3

내 유스 케이스가 None일부 기본값 으로 바뀌 었습니다 .

@kxr-using을 포함하여 여기에 제시된이 문제에 대한 접근 방식을 시간을 정했습니다 str.count.

Python 3.8.1을 사용하여 ipython에서 테스트 코드 :

def rep1(lst, replacer = 0):
    ''' List comprehension, new list '''

    return [item if item is not None else replacer for item in lst]


def rep2(lst, replacer = 0):
    ''' List comprehension, in-place '''    
    lst[:] =  [item if item is not None else replacer for item in lst]

    return lst


def rep3(lst, replacer = 0):
    ''' enumerate() with comparison - in-place '''
    for idx, item in enumerate(lst):
        if item is None:
            lst[idx] = replacer

    return lst


def rep4(lst, replacer = 0):
    ''' Using str.index + Exception, in-place '''

    idx = -1
    # none_amount = lst.count(None)
    while True:
        try:
            idx = lst.index(None, idx+1)
        except ValueError:
            break
        else:
            lst[idx] = replacer

    return lst


def rep5(lst, replacer = 0):
    ''' Using str.index + str.count, in-place '''

    idx = -1
    for _ in range(lst.count(None)):
        idx = lst.index(None, idx+1)
        lst[idx] = replacer

    return lst


def rep6(lst, replacer = 0):
    ''' Using map, return map iterator '''

    return map(lambda item: item if item is not None else replacer, lst)


def rep7(lst, replacer = 0):
    ''' Using map, return new list '''

    return list(map(lambda item: item if item is not None else replacer, lst))


lst = [5]*10**6
# lst = [None]*10**6

%timeit rep1(lst)    
%timeit rep2(lst)    
%timeit rep3(lst)    
%timeit rep4(lst)    
%timeit rep5(lst)    
%timeit rep6(lst)    
%timeit rep7(lst)    

나는 얻다:

26.3 ms ± 163 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
29.3 ms ± 206 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
33.8 ms ± 191 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
11.9 ms ± 37.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
11.9 ms ± 60.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
260 ns ± 1.84 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
56.5 ms ± 204 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

내부를 사용하는 str.index것이 실제로 수동 비교보다 빠릅니다.

테스트 4의 예외가을 사용 str.count하는 것 보다 더 힘들지 여부는 몰랐습니다 . 차이는 무시할 만합니다.

참고 map()7 테스트 따라서 (실험 6) 반복자 아닌 실제의리스트를 반환한다.


3

긴 목록과 드문 경우 list.index()에는 다른 답변에 제시된 단일 단계 반복 방법과 비교 하여 약 3 배 빠릅니다 .

def list_replace(lst, old=1, new=10):
    """replace list elements (inplace)"""
    i = -1
    try:
        while 1:
            i = lst.index(old, i + 1)
            lst[i] = new
    except ValueError:
        pass

이것이 내가 찾은 가장 빠른 방법입니다. 내 답변의 타이밍을 참조하십시오. 큰!
dawg

2

파이썬에서 간단히 목록 이해를 사용할 수 있습니다.

def replace_element(YOUR_LIST, set_to=NEW_VALUE):
    return [i
            if SOME_CONDITION
            else NEW_VALUE
            for i in YOUR_LIST]

귀하의 경우, 1의 모든 발생을 10으로 바꾸려는 경우 코드 스 니펫은 다음과 같습니다.

def replace_element(YOUR_LIST, set_to=10):
    return [i
            if i != 1  # keeps all elements not equal to one
            else set_to  # replaces 1 with 10
            for i in YOUR_LIST]

3
이 코드 스 니펫은 문제를 해결할 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 실제로 도움이됩니다. 앞으로 독자들에게 질문에 대한 답변을 제공하므로 해당 사람들이 코드 제안의 이유를 모를 수도 있습니다. 설명 주석으로 코드를 복잡하게 만들지 마십시오. 코드와 설명의 가독성이 떨어집니다!
Filnor

-1

하나의 항목 만 찾아서 교체

ur_list = [1,2,1]     # replace the first 1 wiz 11

loc = ur_list.index(1)
ur_list.remove(1)
ur_list.insert(loc, 11)

----------
[11,2,1]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.