簡體   English   中英

按鍵值拆分字典列表-與pop一樣?

[英]Split off list of dicts by key value - as with pop?

我已經看過Python:從列表中刪除字典並將字典列表 拆分為幾個字典列表 -但是這個問題略有不同。

考慮以下工作示例(與Python 2或3相同):

#!/usr/bin/env python
from __future__ import print_function

origarr = [
  { 'name': 'test01', 'type': 0, 'value': 42 },
  { 'name': 'test02', 'type': 0, 'value': 142 },
  { 'name': 'test03', 'type': 2, 'value': 242 },
  { 'name': 'test04', 'type': 2, 'value': 342 },
  { 'name': 'test05', 'type': 3, 'value': 42 },
]

print("origarr: {}".format(origarr))

lastdictelem = origarr.pop()

print("\nlastdictelem: {}".format(lastdictelem))
print("after pop, origarr: {}".format(origarr))

namestofilter = [ 'test01', 'test02' ]
newarr = []
for iname in namestofilter:
  # find the object having the name iname
  foundidx = -1
  for ix, idict in enumerate(origarr):
    if idict.get('name') == iname:
      foundidx = ix
      break
  if foundidx > -1:
    # remove dict object via pop at index, save removed object
    remdict = origarr.pop(foundidx)
    # add removed object to newarr:
    newarr.append(remdict)

print("\nafter namestofilter:")
print("newarr: {}".format(newarr))
print("origarr: {}".format(origarr))

基本上, mylist.pop()mylist刪除最后一個元素作為對象(這里是字典),然后將其返回-然后,我可以將其簡單地插入到新的數組/列表中; 此腳本的第一個打印輸出說明了這一點:

$ python2 test.py 
origarr: [{'name': 'test01', 'type': 0, 'value': 42}, {'name': 'test02', 'type': 0, 'value': 142}, {'name': 'test03', 'type': 2, 'value': 242}, {'name': 'test04', 'type': 2, 'value': 342}, {'name': 'test05', 'type': 3, 'value': 42}]

lastdictelem: {'name': 'test05', 'type': 3, 'value': 42}
after pop, origarr: [{'name': 'test01', 'type': 0, 'value': 42}, {'name': 'test02', 'type': 0, 'value': 142}, {'name': 'test03', 'type': 2, 'value': 242}, {'name': 'test04', 'type': 2, 'value': 342}]

現在,我想做的是定義一個數組,為字典中的name鍵提供值(例如, namestofilter = [ 'test01', 'test02' ] ),然后將這些字典從原始數組/列表中刪除,並放入新的數組/列表中(就像.pop()將處理單個元素和對象引用一樣)。

由於pop會在特定索引處刪除該項目並返回它 ,因此上面的代碼完全可以做到這一點-並且可以正常工作:

...
after namestofilter:
newarr: [{'name': 'test01', 'type': 0, 'value': 42}, {'name': 'test02', 'type': 0, 'value': 142}]
origarr: [{'name': 'test03', 'type': 2, 'value': 242}, {'name': 'test04', 'type': 2, 'value': 342}]

......但我想知道-有這樣做的更緊湊的方式,比“手動”其他for通過兩個數組-looping,並調用.pop() / .append()單獨(如上面的例子一樣) ?

我不確定是否有緊湊的方法-可能沒有。

但是,您可以簡化一些代碼,也不必為每個.pop花費O(n)

origarr = [
  { 'name': 'test01', 'type': 0, 'value': 42 },
  { 'name': 'test02', 'type': 0, 'value': 142 },
  { 'name': 'test03', 'type': 2, 'value': 242 },
  { 'name': 'test04', 'type': 2, 'value': 342 },
  { 'name': 'test05', 'type': 3, 'value': 42 },
]

namestofilter = set([ 'test01', 'test02' ]). # could be a list as in question
print("origarr: {}".format(origarr))

lastdictelem = origarr.pop()

print("\nlastdictelem: {}".format(lastdictelem))
print("after pop, origarr: {}".format(origarr))

shift = 0
newarr = []
for ix, idict in enumerate(origarr):
    if idict['name'] in namestofilter:
        shift += 1
        newarr.append(idict)
        continue
    origarr[ix-shift] = origarr[ix]
origarr = origarr[:-shift]  # perhaps it is a slicing O(n) copy overhead 

print("\nafter namestofilter:")
print("newarr: {}".format(newarr))
print("origarr: {}".format(origarr))

輸出:

origarr: [{'name': 'test01', 'type': 0, 'value': 42}, {'name': 'test02', 'type': 0, 'value': 142}, {'name': 'test03', 'type': 2, 'value': 242}, {'name': 'test04', 'type': 2, 'value': 342}, {'name': 'test05', 'type': 3, 'value': 42}]

lastdictelem: {'name': 'test05', 'type': 3, 'value': 42}
after pop, origarr: [{'name': 'test01', 'type': 0, 'value': 42}, {'name': 'test02', 'type': 0, 'value': 142}, {'name': 'test03', 'type': 2, 'value': 242}, {'name': 'test04', 'type': 2, 'value': 342}]

after namestofilter:
newarr: [{'name': 'test01', 'type': 0, 'value': 42}, {'name': 'test02', 'type': 0, 'value': 142}]
origarr: [{'name': 'test03', 'type': 2, 'value': 242}, {'name': 'test04', 'type': 2, 'value': 342}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM