[英]Removing List from List of Lists with condition
我有這個項目列表,我想從最后一個項目到項目n一個接一個地刪除它,直到它達到預算的總值= 325.000
from collections import namedtuple
Item = namedtuple('Item', 'region sector name budget target performance'.split())
sorted_KP = [Item(region='H', sector='2', name='H3', budget=7000.0, target=1.0, performance=4.0),
Item(region='H', sector='2', name='H10', budget=35000.0, target=15.0, performance=1.0),
Item(region='I', sector='2', name='I6', budget=50000.0, target=5.0, performance=0.40598931548848194),
Item(region='E', sector='4', name='E5', budget=75000.0, target=30.0, performance=0.0663966081766),
Item(region='C', sector='1', name='C1', budget=75000.0, target=50.0, performance=0.0308067750379),
Item(region='C', sector='1', name='C2', budget=75000.0, target=50.0, performance=0.0308067750379),
Item(region='C', sector='5', name='C4', budget=75000.0, target=50.0, performance=0.0308067750379),
Item(region='I', sector='2', name='I5', budget=100000.0, target=5.0, performance=0.40598931548848194),
Item(region='E', sector='4', name='E1', budget=100000.0, target=30.0, performance=0.0663966081766),
Item(region='D', sector='5', name='D21', budget=60000.0, target=4.0, performance=0.2479775110248),
Item(region='D', sector='5', name='D30', budget=10000.0, target=1.0, performance=0.1653183406832),
Item(region='D', sector='1', name='D23', budget=30000.0, target=20.0, performance=0.023659703723372342),
Item(region='C', sector='5', name='C3', budget=150000.0, target=75.0, performance=0.0308067750379),
Item(region='D', sector='5', name='D20', budget=30000.0, target=5.0, performance=0.0826591703416),
Item(region='H', sector='2', name='H6', budget=310576.0, target=1.0, performance=4.0),
Item(region='H', sector='3', name='H5', budget=9500.0, target=1.0, performance=0.1172008400616),
Item(region='E', sector='6', name='E3', budget=100000.0, target=30.0, performance=0.03747318294316411),
Item(region='G', sector='3', name='G17', budget=75000.0, target=20.0, performance=0.04132095963602382),
Item(region='C', sector='4', name='C5', budget=75000.0, target=25.0, performance=0.0308067750379),
Item(region='C', sector='2', name='C6', budget=30000.0, target=5.0, performance=0.0616135500758),
Item(region='C', sector='2', name='C7', budget=30000.0, target=5.0, performance=0.0616135500758),
Item(region='D', sector='6', name='D22', budget=65190.0, target=30.0, performance=0.020332158889648923),
Item(region='D', sector='5', name='D3', budget=100000.0, target=20.0, performance=0.0413295851708),
Item(region='D', sector='5', name='D4', budget=100000.0, target=20.0, performance=0.0413295851708),
Item(region='A', sector='1', name='A12', budget=25000.0, target=25.0, performance=0.00749432996938),
Item(region='A', sector='1', name='A13', budget=25000.0, target=25.0, performance=0.00749432996938),
Item(region='A', sector='3', name='A25', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='5', name='A26', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='1', name='A27', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='1', name='A29', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='3', name='A30', budget=4500.0, target=1.0, performance=0.02997731987752)]
但除了總價值之外,我還有另外兩個項目的條件是否應該刪除。
首先,在刪除項目之后,仍然存在代表相同區域的列表列表中的至少一個項目
其次,在移除項目之后,仍然存在至少一個表示相同扇區的項目
例如,我可以刪除最后一項,因為它代表區域“A”,剩下5項也代表區域“A”。 它也代表扇區“3”,留下3個代表扇區“3”的項目。
重復此刪除和檢查,直到我達到總移除預算至少325.000
我做了這個代碼,但我無法得到我需要的東西。 請幫我糾正一下。
from collections import Counter
unpack = []
for item in sorted_KP:
item_budget = item[3]
sum_unpack = sum(item[3] for item in unpack)
budget = 325000
remaining = []
for item in sorted_KP:
if item not in unpack:
remaining.append(item)
region_el = [item[0] for item in remaining]
counter_R_el = Counter(region_el)
sector_el = [item[1] for item in remaining]
counter_S_el = Counter(sector_el)
if counter_R_el >= 1 or counter_S_el >= 1:
if sum_unpack <= budget:
unpack.append(item)
for item in unpack:
print "\t", item
這是我的代碼,第25項仍然刪除時,它不應該:
unpack =Item(region='A', sector='3', name='A30', budget=4500.0, target=1.0, performance=0.02997731987752)
Item(region='A', sector='1', name='A29', budget=4500.0, target=1.0, performance=0.02997731987752)
Item(region='A', sector='1', name='A27', budget=4500.0, target=1.0, performance=0.02997731987752)
Item(region='A', sector='5', name='A26', budget=4500.0, target=1.0, performance=0.02997731987752)
Item(region='A', sector='3', name='A25', budget=4500.0, target=1.0, performance=0.02997731987752)
Item(region='A', sector='1', name='A13', budget=25000.0, target=25.0, performance=0.00749432996938)
Item(region='A', sector='1', name='A12', budget=25000.0, target=25.0, performance=0.00749432996938)
Item(region='D', sector='5', name='D4', budget=100000.0, target=20.0, performance=0.0413295851708)
Item(region='D', sector='5', name='D3', budget=100000.0, target=20.0, performance=0.0413295851708)
Item(region='D', sector='6', name='D22', budget=65190.0, target=30.0, performance=0.020332158889648923)
項目25(項目名稱:“A12”)無法刪除,即使我們仍有預算要刪除,因為如果刪除,則不再有項目代表區域“A”,依此類推。
雖然解決方案應該是:
unpack = [Item(region='A', sector='3', name='A30', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='1', name='A29', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='1', name='A27', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='5', name='A26', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='3', name='A25', budget=4500.0, target=1.0, performance=0.02997731987752),
Item(region='A', sector='1', name='A13', budget=25000.0, target=25.0, performance=0.00749432996938),
Item(region='D', sector='5', name='D4', budget=100000.0, target=20.0, performance=0.0413295851708),
Item(region='D', sector='5', name='D3', budget=100000.0, target=20.0, performance=0.0413295851708),
Item(region='D', sector='6', name='D22', budget=65190.0, target=30.0, performance=0.020332158889648923),
Item(region='C', sector='2', name='C7', budget=30000.0, target=5.0, performance=0.0616135500758)]
預先感謝您的幫助
在我實際嘗試運行它時更新答案我發現了一些其他問題:
for item in sorted_KP
使用與外部循環相同的item
計數器並覆蓋它 - 始終嘗試刪除A30
(最后)項目 item2
,我還必須反轉外循環順序(即從最后一行開始刪除)。 TypeError: unorderable types: Counter() >= int()
- 需要根據需要選擇匹配項目區域或扇區的特定計數 and
你的2個額外條件,不是or
他們 > 1
,而不是>= 1
實際測試的代碼:
>>> for item in sorted_KP[::-1]:
... item_budget = item[3]
... sum_unpack = sum(item[3] for item in unpack)
... budget = 325000
... remaining = []
... for item2 in sorted_KP:
... if item2 not in unpack:
... remaining.append(item2)
... region_el = [item[0] for item in remaining]
... counter_R_el = Counter(region_el)
... sector_el = [item[1] for item in remaining]
... counter_S_el = Counter(sector_el)
... if counter_R_el[item.region] > 1 and counter_S_el[item.sector] > 1:
... if sum_unpack <= budget:
... unpack.append(item)
...
>>>
>>> for item in unpack:
... logging.error(item)
...
ERROR:root:Item(region='A', sector='3', name='A30', budget=4500.0, target=1.0, performance=0.02997731987752)
ERROR:root:Item(region='A', sector='1', name='A29', budget=4500.0, target=1.0, performance=0.02997731987752)
ERROR:root:Item(region='A', sector='1', name='A27', budget=4500.0, target=1.0, performance=0.02997731987752)
ERROR:root:Item(region='A', sector='5', name='A26', budget=4500.0, target=1.0, performance=0.02997731987752)
ERROR:root:Item(region='A', sector='3', name='A25', budget=4500.0, target=1.0, performance=0.02997731987752)
ERROR:root:Item(region='A', sector='1', name='A13', budget=25000.0, target=25.0, performance=0.00749432996938)
ERROR:root:Item(region='D', sector='5', name='D4', budget=100000.0, target=20.0, performance=0.0413295851708)
ERROR:root:Item(region='D', sector='5', name='D3', budget=100000.0, target=20.0, performance=0.0413295851708)
ERROR:root:Item(region='D', sector='6', name='D22', budget=65190.0, target=30.0, performance=0.020332158889648923)
ERROR:root:Item(region='C', sector='2', name='C7', budget=30000.0, target=5.0, performance=0.0616135500758)
>>>
假設您在使用print
without ()
使用Python 2。
請參閱修改后的代碼中的注釋:
unpack = []
for item in sorted_KP[::-1]: # loop the items in reverse order
#item_budget = item[3] # variable not used
sum_unpack = sum(item[3] for item in unpack)
budget = 325000
remaining = []
for x in sorted_KP: # don't use 'item' here as in Python 2, it will modify the variable 'item' in the outer loop
if x not in unpack:
remaining.append(x)
region_el = [x[0] for x in remaining] # don't use 'item' here as well
counter_R_el = Counter(region_el)
sector_el = [x[1] for x in remaining] # don't use 'item' here as well
counter_S_el = Counter(sector_el)
#if counter_R_el >= 1 or counter_S_el >= 1: # note that result is always True in Python 2
if counter_R_el[item.region] > 1 and counter_S_el[item.sector] > 1: # check '> 1' instead of '>= 1', and use 'and' instead of 'or'
if sum_unpack <= budget:
unpack.append(item)
for item in unpack:
print "\t", item
我建議的解決方案
budget = 325000
sum = 0 # accumulated budget of removed items
removed_KP = [] # holds the removed items
for item in sorted_KP[::-1]:
# stop checking if over-budget
if sum >= budget: break
# check whether there are items with same region and sector
rcnt = scnt = 0
for tmp in sorted_KP:
if tmp.region == item.region: rcnt += 1
if tmp.sector == item.sector: scnt += 1
if scnt > 1 and rcnt > 1:
# this item can be removed based on the constraints
sorted_KP.remove(item)
removed_KP.append(item)
sum += item.budget
# print the removed items
for item in removed_KP:
print(item)
我無法輕松整理您的代碼。 if counter_R_el >= 1 or counter_S_el >= 1:
只是無法工作,則無法將Counter()與int()進行比較。 它看起來像你不斷重制/重置你的循環套件中的東西 ,它變得令人困惑。
你似乎走在了正確的軌道上。
這是我想出的:
import collections, operator
Item = collections.namedtuple('Item', ['region', 'sector', 'name',
'budget', 'target', 'performance'])
a = [Item(region='H', sector='2', name='H3', budget=7000.0, target=1.0, performance=4.0),
Item(region='H', sector='2', name='H10', budget=35000.0, target=15.0, performance=1.0),
Item(region='I', sector='2', name='I6', budget=50000.0, target=5.0, performance=0.40598931548848194),
.....]
budget = 325000
# sort highest to lowest cost
a.sort(key = operator.attrgetter('budget'), reverse = True)
project_cost = sum(item.budget for item in a)
# constraint counters
region_count = collections.Counter(item.region for item in a)
sector_count = collections.Counter(item.sector for item in a)
# iterate over a copy of the list
b = a.copy()
for item in b:
if project_cost <= budget:
break
# check item against constraints
if region_count[item.region] > 1 and sector_count[item.sector] > 1:
# remove the item from the original list
a.remove(item)
# uodate the counters and cost
region_count[item.region] -= 1
sector_count[item.sector] -= 1
project_cost -= item.budget
a
包含符合約束條件且總成本低於預算的項目。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.