python用两个不同列表中的值替换列表的布尔值

2024-10-01 09:40:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有布尔值的列表,比如

lyst = [True,True,False,True,False]

以及两个不同的列表,例如:

^{pr2}$

我只想用car中的值替换True,用a中的值替换False。 或者使用来自lyst的序列和来自cara的值创建一个新列表。 结果应该是

[BMW,VW,b,Volvo,c].

目前我的代码:

for elem1,elem2,elem3 in zip(lyst,car,a):
    subelem2=elem2
    subelem3=elem3
    if elem1 != True:
        result_list.append(subelem2)
    else: 
        result_list.append(subelem3)

但这会创建一个长度超过5的列表匹配。在

我该怎么做?在


Tags: falsetrue列表序列resultcarlistappend
3条回答

假设在lyst中有正确数量的True和{}个条目,那么您可以通过创建其他两个列表的迭代器来有效地实现这一点。这比列表前面的pop更有效。在

lyst = [True, True, False, True, False]
car = ['BMW', 'VW', 'Volvo']
a = ['b', 'c']
selector = [iter(a), iter(car)]
result = [next(selector[b]) for b in lyst]
print(result)

输出

^{pr2}$

selector[b]构造有效,因为False的数值为0,True的数值为1,因此我们可以使用lyst的布尔值来索引到selector列表中。在


时间安排

我决定编写一个^{}脚本来比较这里发布的各种算法的速度,以及来自{a2}的vaultah代码。在

为了测试这些算法,我把它们都放到函数中。为了获得精确的计时数据,timeit多次运行函数。使用.pop的算法使用它们弹出的列表,因此我必须向这些函数添加代码以创建这些列表的副本。显然,复制过程会减慢这些函数的速度,在某些应用程序中,输入数据列表被破坏可能无关紧要,但我觉得需要包括复制时间,以便比较这些函数的速度,以便更通用。在

timeit测量的是挂钟时间,而不是CPU时间,因此计时将受到系统上运行的其他进程的影响。因此,在运行timeit代码时,最好尽可能减少系统负载。理想情况下,您应该关闭netaccess,或者至少避免在测试运行时使用浏览器。绝对不要听音乐或看视频。:)

下面的代码运行在python2.6+和python3上。我在python2.6.6和python3.6.0上进行了测试。在

#!/usr/bin/env python3

''' Merge two lists according to a list of booleans

    Given data lists `alist` and `blist`, iterate over boolean list `chooser`.
    If the current item in `chooser` is False, append the next item from `alist`
    to the output list.
    If the current item in `chooser` is True, append the next item from `blist`
    to the output list.

    See https://stackoverflow.com/q/42028606/4014959

    Speed tests of implementations by various authors
    Timing code written by PM 2Ring 2016.12.28
'''

# Python 2 / 3 compatible

from __future__ import print_function, division
from timeit import Timer
from random import seed, shuffle

seed(1234)

# The functions to test

def merge_wwii_ifelse(alist, blist, chooser):
    alist = iter(alist)
    blist = iter(blist)
    return [next(blist) if item else next(alist) for item in chooser]

def merge_wwii_andor(alist, blist, chooser):
    alist = iter(alist)
    blist = iter(blist)
    return [(flag and next(blist)) or next(alist) for flag in chooser]

def merge_PM2R_it(alist, blist, chooser):
    selector = [iter(alist), iter(blist)]
    return [next(selector[b]) for b in chooser]

def merge_PM2R_pop(alist, blist, chooser):
    alist = list(alist)
    blist = list(blist)
    return [blist.pop() if item else alist.pop() for item in reversed(chooser)][::-1]

def merge_AlexL(alist, blist, chooser):
    alist = list(alist)
    blist = list(blist)
    return [blist.pop(0) if item else alist.pop(0) for item in chooser]

def merge_Laurent(alist, blist, chooser):
    selector = {True: iter(blist), False: iter(alist)}
    return [next(selector[flag]) for flag in chooser]

def merge_Shihab(alist, blist, chooser):
    i = j = 0
    ans = []
    for v in chooser:
        if v:
            ans.append(blist[i])
            i += 1
        else:
            ans.append(alist[j])
            j += 1
    return ans

def merge_EvKounis(alist, blist, chooser):
    mapping = {True: list(blist), False: list(alist)}
    return [mapping[c].pop(0) for c in chooser]

def merge_vaultah(alist, blist, chooser):
    i1 = iter(alist)
    i2 = iter(blist)
    return [next(i2 if x else i1) for x in chooser]

funcs = (
    merge_wwii_ifelse,
    merge_wwii_andor,
    merge_PM2R_it,
    merge_PM2R_pop,
    merge_AlexL,
    merge_Laurent,
    merge_Shihab,
    merge_EvKounis,
    merge_vaultah,
)

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

def qdata_test():
    print('Testing all functions with the question data')
    alist, blist, chooser = (
        ['b', 'c'],
        ['BMW', 'VW', 'Volvo'], 
        [True, True, False, True, False],
    )

    expected = ['BMW', 'VW', 'b', 'Volvo', 'c']
    print('Expected:', expected)
    for func in funcs:
        print(func.__name__, func(alist, blist, chooser) == expected)

def make_data(size):
    ''' Create two equal-sized data lists and a random chooser list '''
    a = list(range(1, size + 1))
    b = [-u for u in a]
    c = [False] * size + [True] * size
    shuffle(c)
    return a, b, c

def verify():
    results = [func(alist, blist, chooser) for func in funcs]
    first = results[0]
    return all(first == u for u in results[1:])

def time_test(loops, reps):
    ''' Print timing stats for all the functions '''
    timings = []
    for func in funcs:
        fname = func.__name__
        setup = 'from __main__ import alist, blist, chooser, ' + fname
        cmd = '{0}(alist, blist, chooser)'.format(fname)
        t = Timer(cmd, setup)
        result = t.repeat(reps, loops)
        result.sort()
        timings.append((result, fname))

    timings.sort()
    for result, fname in timings:
        print('{0:18} {1}'.format(fname, result))

qdata_test()

maxloops = 5 ** 7
for i in range(1, 7):
    size = 5 ** i
    loops, reps = maxloops // size, 3
    print('\nList size = {0}, loops = {1}'.format(size, loops))

    alist, blist, chooser = make_data(size)
    print('All functions verified', verify())

    time_test(loops, reps)    

Python 3输出

Testing all functions with the question data
Expected: ['BMW', 'VW', 'b', 'Volvo', 'c']
merge_wwii_ifelse True
merge_wwii_andor True
merge_PM2R_it True
merge_PM2R_pop True
merge_AlexL True
merge_Laurent True
merge_Shihab True
merge_EvKounis True
merge_vaultah True

List size = 5, loops = 15625
All functions verified True
merge_Shihab       [0.1553873940010817, 0.15573736099941016, 0.1570748160011135]
merge_vaultah      [0.19238512099946092, 0.19444048600053065, 0.19622620799964352]
merge_wwii_ifelse  [0.1928826420007681, 0.20096588600063114, 0.2038269639997452]
merge_wwii_andor   [0.19839437199880194, 0.19887267900048755, 0.1997791949997918]
merge_PM2R_it      [0.21258554000087315, 0.21627756400084763, 0.21734632500010775]
merge_Laurent      [0.22584542599906854, 0.22584707799978787, 0.2275525179993565]
merge_PM2R_pop     [0.252919409000242, 0.2563238849998015, 0.28485306599941396]
merge_AlexL        [0.295069166999383, 0.2970452879999357, 0.3192335510011617]
merge_EvKounis     [0.3210714779997943, 0.32545770300021104, 0.3283817559986346]

List size = 25, loops = 3125
All functions verified True
merge_wwii_andor   [0.13853849199949764, 0.13861457399980281, 0.16665312800068932]
merge_vaultah      [0.1385455899999215, 0.13872790400091617, 0.13888424499964458]
merge_wwii_ifelse  [0.14001116700092098, 0.1411627879988373, 0.14938874099971144]
merge_PM2R_pop     [0.1415618489991175, 0.14180967100037378, 0.14234910300001502]
merge_Shihab       [0.1417505749996053, 0.14575945399883494, 0.1469801869989169]
merge_PM2R_it      [0.15280632599933597, 0.1578172520003136, 0.20611876800103346]
merge_Laurent      [0.15372244299942395, 0.15373632599948905, 0.15608775699911348]
merge_AlexL        [0.19783953799924348, 0.19835066099949472, 0.19853855400106113]
merge_EvKounis     [0.21501469599934353, 0.21525065300011192, 0.21861338300004718]

List size = 125, loops = 625
All functions verified True
merge_PM2R_pop     [0.10481183099909686, 0.10530150200065691, 0.1054428099996585]
merge_vaultah      [0.12480986199989275, 0.125469589000204, 0.12560611799926846]
merge_wwii_andor   [0.1248406070008059, 0.1251086979991669, 0.12896737399933045]
merge_wwii_ifelse  [0.1248461369996221, 0.12487849500030279, 0.1357243729999027]
merge_Shihab       [0.13901417600027344, 0.14433371599989187, 0.14757765399917844]
merge_Laurent      [0.14081091899970488, 0.14126963899980183, 0.21554046200071753]
merge_PM2R_it      [0.14273404000050505, 0.1436745359987981, 0.14957189699998708]
merge_AlexL        [0.1876233860002685, 0.18891249499938567, 0.2016287040005409]
merge_EvKounis     [0.20533967399933317, 0.2060009060005541, 0.2169854090006993]

List size = 625, loops = 125
All functions verified True
merge_PM2R_pop     [0.10215267800049332, 0.10283978299958108, 0.10370849799983262]
merge_vaultah      [0.12245723900014127, 0.1226432970015594, 0.12315383100030886]
merge_wwii_ifelse  [0.12513774199942418, 0.12616848099969502, 0.12886606600113737]
merge_wwii_andor   [0.12801914100055, 0.12805822200061812, 0.12933381000038935]
merge_PM2R_it      [0.137118164999265, 0.13727735000065877, 0.1388498169999366]
merge_Laurent      [0.138064671000393, 0.1399875509996491, 0.1408491909987788]
merge_Shihab       [0.14056324699959077, 0.14599118399928557, 0.190011668999432]
merge_AlexL        [0.2494661869986885, 0.24949409599867067, 0.25023536899971077]
merge_EvKounis     [0.2604512350008008, 0.2616422920000332, 0.26348238600076]

List size = 3125, loops = 25
All functions verified True
merge_PM2R_pop     [0.10108045999913884, 0.1956245539986412, 0.19625802900009148]
merge_vaultah      [0.1205880960005743, 0.12112638399958087, 0.12208285199994862]
merge_wwii_andor   [0.12255161999928532, 0.12333094499990693, 0.12521908300004725]
merge_wwii_ifelse  [0.12545375700028671, 0.12909694299924013, 0.1335049829995114]
merge_PM2R_it      [0.13350266700035718, 0.1339889190003305, 0.13768064900068566]
merge_Laurent      [0.13691045599989593, 0.1544653910004854, 0.15945969300082652]
merge_Shihab       [0.13996293700074602, 0.14073836100033077, 0.15528064499994798]
merge_AlexL        [0.5525499420000415, 0.562283696999657, 0.954857885999445]
merge_EvKounis     [0.5699720739994518, 0.5713485720007156, 0.57778780100125]

List size = 15625, loops = 5
All functions verified True
merge_PM2R_pop     [0.10786392400041223, 0.10926139099865395, 0.10992666599850054]
merge_vaultah      [0.12552327299999888, 0.1260173209993809, 0.126270750999538]
merge_wwii_ifelse  [0.13077028499901644, 0.13549192800019227, 0.13690466499974718]
merge_wwii_andor   [0.13939281700004358, 0.14145590299995092, 0.1771287490009854]
merge_Laurent      [0.14111154199963494, 0.141571592001128, 0.14596649399936723]
merge_PM2R_it      [0.14352190899990092, 0.1444555029993353, 0.1446186849989317]
merge_Shihab       [0.1475988830006827, 0.14831254499949864, 0.15240716699918266]
merge_AlexL        [2.040518506999433, 2.0523803409996617, 2.1246015890010312]
merge_EvKounis     [2.0611778700003924, 2.0809960999995383, 2.0933345120010927]

Python 2输出

Testing all functions with the question data
Expected: ['BMW', 'VW', 'b', 'Volvo', 'c']
merge_wwii_ifelse True
merge_wwii_andor True
merge_PM2R_it True
merge_PM2R_pop True
merge_AlexL True
merge_Laurent True
merge_Shihab True
merge_EvKounis True
merge_vaultah True

List size = 5, loops = 15625
All functions verified True
merge_wwii_ifelse  [0.13266801834106445, 0.13341188430786133, 0.14590716361999512]
merge_vaultah      [0.1372370719909668, 0.20317387580871582, 0.28184700012207031]
merge_wwii_andor   [0.1373291015625, 0.14022302627563477, 0.14162182807922363]
merge_Shihab       [0.14127588272094727, 0.14717292785644531, 0.15103507041931152]
merge_PM2R_it      [0.16237378120422363, 0.16309309005737305, 0.1668241024017334]
merge_Laurent      [0.18718504905700684, 0.21074390411376953, 0.24513697624206543]
merge_PM2R_pop     [0.28445720672607422, 0.29493808746337891, 0.32616496086120605]
merge_EvKounis     [0.29379916191101074, 0.33054614067077637, 0.34055399894714355]
merge_AlexL        [0.29791903495788574, 0.29801201820373535, 0.31824994087219238]

List size = 25, loops = 3125
All functions verified True
merge_vaultah      [0.10121989250183105, 0.10190892219543457, 0.10230588912963867]
merge_wwii_andor   [0.10298919677734375, 0.10324811935424805, 0.1042180061340332]
merge_wwii_ifelse  [0.10428714752197266, 0.1065058708190918, 0.13893890380859375]
merge_PM2R_it      [0.11803603172302246, 0.11927890777587891, 0.12329411506652832]
merge_Shihab       [0.12048506736755371, 0.1209111213684082, 0.14031100273132324]
merge_Laurent      [0.12093997001647949, 0.12250900268554688, 0.12366700172424316]
merge_PM2R_pop     [0.14476203918457031, 0.14788198471069336, 0.15009903907775879]
merge_AlexL        [0.2096550464630127, 0.2101140022277832, 0.21013402938842773]
merge_EvKounis     [0.22748994827270508, 0.24114799499511719, 0.27338886260986328]

List size = 125, loops = 625
All functions verified True
merge_wwii_ifelse  [0.093290090560913086, 0.095035076141357422, 0.10503697395324707]
merge_wwii_andor   [0.095438957214355469, 0.096124887466430664, 0.096685171127319336]
merge_vaultah      [0.096237897872924805, 0.096857070922851562, 0.10109710693359375]
merge_Laurent      [0.11233901977539062, 0.11253595352172852, 0.11261391639709473]
merge_PM2R_it      [0.11286282539367676, 0.11314296722412109, 0.11331295967102051]
merge_PM2R_pop     [0.11631202697753906, 0.11657595634460449, 0.11874699592590332]
merge_Shihab       [0.12019991874694824, 0.12040495872497559, 0.12069797515869141]
merge_AlexL        [0.21399688720703125, 0.21718001365661621, 0.23727011680603027]
merge_EvKounis     [0.22643208503723145, 0.22728395462036133, 0.22952795028686523]

List size = 625, loops = 125
All functions verified True
merge_wwii_ifelse  [0.091418981552124023, 0.091669797897338867, 0.097893953323364258]
merge_vaultah      [0.092507839202880859, 0.09267878532409668, 0.09857487678527832]
merge_wwii_andor   [0.094152212142944336, 0.094262123107910156, 0.095048904418945312]
merge_PM2R_pop     [0.10612797737121582, 0.10874819755554199, 0.15479302406311035]
merge_Laurent      [0.10751605033874512, 0.10817885398864746, 0.1108400821685791]
merge_PM2R_it      [0.10856819152832031, 0.10870695114135742, 0.10909485816955566]
merge_Shihab       [0.12109684944152832, 0.12231802940368652, 0.12318301200866699]
merge_AlexL        [0.26717281341552734, 0.27173185348510742, 0.27331304550170898]
merge_EvKounis     [0.27798080444335938, 0.27915000915527344, 0.28347897529602051]

List size = 3125, loops = 25
All functions verified True
merge_wwii_ifelse  [0.089553117752075195, 0.090708017349243164, 0.096336126327514648]
merge_wwii_andor   [0.092846870422363281, 0.092998027801513672, 0.09307098388671875]
merge_vaultah      [0.093343973159790039, 0.096785068511962891, 0.11030793190002441]
merge_Laurent      [0.10524392127990723, 0.10576510429382324, 0.10692310333251953]
merge_PM2R_pop     [0.10529899597167969, 0.10684394836425781, 0.1188349723815918]
merge_PM2R_it      [0.1075129508972168, 0.1087181568145752, 0.11004185676574707]
merge_Shihab       [0.12116694450378418, 0.1221461296081543, 0.12650799751281738]
merge_AlexL        [0.57863092422485352, 0.58119797706604004, 0.62129878997802734]
merge_EvKounis     [0.59500694274902344, 0.59542298316955566, 0.59793877601623535]

List size = 15625, loops = 5
All functions verified True
merge_wwii_ifelse  [0.093538999557495117, 0.094748973846435547, 0.099496126174926758]
merge_wwii_andor   [0.097050189971923828, 0.097167015075683594, 0.14334392547607422]
merge_vaultah      [0.097479820251464844, 0.097939968109130859, 0.10231399536132812]
merge_Laurent      [0.10894298553466797, 0.10906291007995605, 0.11107587814331055]
merge_PM2R_pop     [0.11378717422485352, 0.11389708518981934, 0.11422491073608398]
merge_PM2R_it      [0.11379504203796387, 0.1164860725402832, 0.11690497398376465]
merge_Shihab       [0.12729287147521973, 0.12743711471557617, 0.12863397598266602]
merge_AlexL        [2.062777042388916, 2.0632898807525635, 2.104421854019165]
merge_EvKounis     [2.0776879787445068, 2.1075038909912109, 2.1273050308227539]

这些结果来自我相当古老的32位单核2GHZ机器,2GB的RAM运行着Debian Linux的衍生产品。在

car = iter(car)
a = iter(a)
[next(car) if item else next(a) for item in lyst]

好吧,我忍不住:

^{pr2}$

这将使用一些布尔表达式功能:

  • 如果第一个操作数为False,则布尔and表达式将不计算第二个操作数
  • 如果两个操作数的计算结果都为True,则布尔and表达式将返回第二个操作数(实际对象)
  • 布尔or表达式将返回第一个计算结果为True的对象

一个潜在的问题是car或{}中的任何项的计算结果都为False。同样,这并不像第一个溶液中的三元溶液那么易读。在

但很有趣。在


我想我会再补充一点,我可能不应该重新分配原始的列表名称-我应该为迭代器名称选择不同的名称。一旦用尽,迭代器就无法重置,并且由于列表名称被重新分配,原始列表信息将丢失。在

>>> lyst = [True,True,False,True,False]
>>> car = ['BMW','VW','Volvo']
>>> a = ['b', 'c']
>>> [car.pop(0) if item else a.pop(0) for item in lyst]
['BMW', 'VW', 'b', 'Volvo', 'c']
>>> 

相关问题 更多 >