词典列表中的Pythonic搜索

词典列表中的Pythonic搜索,python,search,dictionary,Python,Search,Dictionary,我的字典结构如下: {ID:[{*},{*},{*},{*},…]} i、 每个ID都有一个字典列表,每个字典代表游戏中的一个动作。本词典的每个内容(用*表示)由这些键构成,列表按gameTime字段排序: userID gameTime gameCode shortDesc d01 d02 d03 d04 chapter level playCnt 我必须编写一个.csv文件,其中填充符合某些条件的用户名对应的数据。也就是说,我必须存储与用户相关的数

我的字典结构如下:

{ID:[{*},{*},{*},{*},…]}

i、 每个ID都有一个字典列表,每个字典代表游戏中的一个动作。本词典的每个内容(用*表示)由这些键构成,列表按
gameTime
字段排序:

userID  gameTime    gameCode    shortDesc   d01   d02   d03   d04   chapter   level   playCnt
我必须编写一个.csv文件,其中填充符合某些条件的用户名对应的数据。也就是说,我必须存储与用户相关的数据,这些用户在某个时候采取了一些行动。 例如,我必须拥有与每个用户ID相关的信息,这些用户ID在某些时候具有以下键/值:

shortDesc:BADGE_OPT

d01:选择加入

由于
d01
是与
shortDescription
相关的数据,我知道当我找到
shortDesc:BADGE_OPT
时,我必须查看
d01:OPT-IN

但是,我也可以找到以下序列:

shortDesc:BADGE_OPT/d01:OPT-IN

shortDesc:BADGE_OPT/d01:OPT-OUT

然后,当
d01=OPT_IN
时,我必须只存储信息,即任何
d01=OPT_OUT/d01=OPT_IN
之间的信息都必须丢弃

因此,在某些情况下,
BADGE_OPT
被打开,但从未被关闭。或者我可以找到一个轮换顺序

我知道我可以迭代我的字典列表,当我第一次找到
d01=OPT_in
时开始录制(在另一个列表中),当我找到
d01=OPT_OUT
时停止录制,等等。但是我想知道是否有一种pythonic的方法可以做到这一点(获取这些细节部分或信息,或者删除不必要的部分)

到目前为止,我一直在尝试这样的事情:

import numpy
import csv
import fileinput
import sys

from itertools import chain

def process_data(file_path):
    users = {}
    
    # Open the .csv file and creates a dict of actions
    with open(file_path, 'rb') as csvfile:
        spamreader = csv.DictReader(csvfile, delimiter='\t', quoting=csv.QUOTE_NONE)
        for row in spamreader:
            conditions = list(row[condition_name[i]] == condition_value[i] for i in range(len(condition_name)))
            if row[event_name] == event_value and all(conditions) == True:  
                # Add an empty list for 'userID' if it is not registered yet in dict
                user = row['subjectID']
                actions = users.get(user, [])
                # Delete the 'userID' from the information
                del row['subjectID']
                # Add a register of actions for this user
                actions.append(row)
                # Update its values
                users[user] = actions
            
    # Sort each list of actions based on time
    for user, event_list in users.iteritems():
        users[user] = sorted(event_list, key=lambda k: k[data])
         
    # Write a .csv to be consumed by the app    
    with open('eventsInput.txt', 'w') as csvfile:
        writer = csv.writer(csvfile, delimiter='\t')
        # Key is the user ID
        # Value is a list of dictionaries of its action per time
        for user, event_list in users.iteritems():
            events = []
            # Produces pairs of event/time
            for event_dict in event_list:
                event = " ".join(event_dict[e] for e in event_fields)
                time = event_dict[data]
                events.append(event)
                events.append(time)
            writer.writerow([user, 1, 2, 0, 4, str(5)] + events)
            
    # Pos-processing
    if len(pos_condition_name) == 0:
        return
        
    f = fileinput.input('eventsInput.txt', inplace=True)
    w = csv.writer(sys.stdout) 
    spamreader = csv.DictReader(f, delimiter='\t', quoting=csv.QUOTE_NONE)
    for row in spamreader:
        conditions = list(row[pos_condition_name[i]] == pos_condition_value[i] for i in range(len(pos_condition_name)))
        if all(conditions) == True:
            w.writerow(row)

event_name = 'shortDesc'
event_value = 'ANGLE_RULE_ACTION'
event_fields = ['d01', 'd02', 'd03', 'd04']
condition_name = ['level', 'chapter']
condition_value = ['3', '3']
pos_condition_name = ['shortDesc']
pos_condition_value = ['BADGE_OPT']

但这不起作用,至少有两个原因。首先,没有必要每个字典都有
shortDesc=BADGE\u OPT
d01=OPT\u IN
字段。这在这些数据中甚至没有意义。但是,我不能使用
any
进行测试,因为条件可能会在以后出现,我必须只存储与条件值在
的时间段相关的信息。我想说,解决方案的外部部分最好使用两个特别的pythonic for循环构造来解决:

for id,actionlist in bigdict.items():
   opted_in=False  # initial state

   for index,stardict in enumerate(actionlist):
      if stardict['shortDesc'] == 'BADGE_OPT':
          if ( stardict['d01'] == 'OPT-IN') opted_in = True
          if ( stardict['d01'] == 'OPT-OUT' opted_in = False

      # act depending on opted_in state
它看起来很笨拙,但我避免了
opted_in=(stardict['d01']='OPT-in')
,因为不清楚d01是否仅限于这两个值。您可以将最后三行放在
中,然后重试。。。如果
stardict
可能不包含
shortDesc
d01
键,则不包括KeyError

那怎么办呢?当opt_-in为真时,我会用stardict构建一个outdict,但我可能不完全理解这个问题。所以

 outdict={}

 for id,actionlist in bigdict.items():

   opted_in=False  # initial state
   outdict[id] = [] 

   for index,stardict in enumerate(actionlist):
      if stardict['shortDesc'] == 'BADGE_OPT':
          if ( stardict['d01'] == 'OPT-IN') opted_in = True
          if ( stardict['d01'] == 'OPT-OUT' opted_in = False
      if opted_in:
          outdict[id].append( stardict)
然后处理输出。注意,没有复制Stardict,只需将相同的Stardict分配给存储在新outdict中的新列表,因此速度应该可以接受


注意:未测试。

能否向我们展示您为解决此问题而尝试的代码?是的,这看起来像我当前的解决方案。(:我想知道是否有一些
pythonic
magic使用列表理解等等。谢谢。