根据条件将项目附加到不同的列表

时间:2013-07-20 23:07:45

标签: python list

基本上我正在寻找一种方法,可以根据特定条件将列表中的项目附加到两个不同的列表中。

我有一个相当广泛的python 3.3程序来管理在线聊天界面。如果我们有一组用户,例如['bob', 'joe', 'frank', 'jimmy', 'louis'],则他们可以离线或离线。我想将所有在线用户添加到一个列表,将离线用户添加到另一个列表中,这样如果bob和joe在线,那么它们将被附加到“在线”列表中,其余的将被附加到列表“离线” 。之后,我会做类似的事情:

print('online: %s offline: %s' % (', '.join(online), ', '.join(offline))

如果你能告诉我一个有效的方法,我将非常感激。

6 个答案:

答案 0 :(得分:3)

如果我理解正确,您希望将输入列表分为两部分,具体取决于用户的连接状态。假设有一些功能来确定用户是否在线:

users   = ['bob', 'joe', 'frank', 'jimmy', 'louis']
online  = [x for x in users if is_online(x)]
offline = [x for x in users if not is_online(x)]

答案 1 :(得分:3)

我会使用defaultdict(list)并根据您的条件附加到它 - 这也可以很好地扩展到忙/远/ DND等...,然后通过您想要的状态访问它:

from random import choice
from collections import defaultdict

status_choice = ['online', 'offline']
statuses = defaultdict(list)

for name in ['bob', 'joe', 'frank', 'jimmy', 'louis']:
    status = choice(status_choice)
    statuses[status].append(name)

print(statuses)
# defaultdict(<type 'list'>, {'offline': ['joe', 'frank', 'jimmy', 'louis'], 'online': ['bob']})
print(statuses['online'])
# ['bob']

您可能还希望考虑使用set而不是列表来更快地查找/删除/插入名称,并且还会停止发生重复值。

答案 2 :(得分:1)

我曾经使用过这样的东西:

def partition(seq, predicate, if_true, if_false):
    select = if_false, if_true
    for each in seq:
        select[predicate(each)](each)

def divisible_by_3(n):
    return n % 3 == 0

div3s = []
nondiv3s = []

partition(range(1, 11), divisible_by_3, div3s.append, nondiv3s.append)

print div3s, nondiv3s

结果:

[3, 6, 9] [1, 2, 4, 5, 7, 8, 10]

答案 3 :(得分:1)

如果您的应用程序要在一段时间内维护在线和离线用户列表,随着用户加入或离线时内容会发生变化,我认为使用集合的方法最好:

online_users = set(initial_online_users)
offline_users = set(all_users) - online_users

def come_online(user):
    offline_users.remove(user)
    online_users.add(user)

def go_offline(user):
    online_users.remove(user)
    offline_users.add(user)

将用户从在线转移到离线或反之亦然的操作将非常快,即使总用户数量很大。选择每个中的添加和删除顺序,以确保在未知用户被传入时将引发异常(无需在任何地方添加用户)。

答案 4 :(得分:0)

对于长(> 100)列表,这将更快,同时确保用户不会同时在两个列表或两个列表中结束:

users   = ['bob', 'joe', 'frank', 'jimmy', 'louis']
offline = []
online = filter(None, [u if is_online(u) else offline.append(u) for u in users])

答案 5 :(得分:0)

这是我的抨击。

它更容易阅读,但正如其他答案所示,如果这是您的偏好,可以进一步减少。

此示例构建一个函数( getUserStatus(user_list) ),该函数返回主列表中的两个列表(在线/离线)( [[“online1”,“online2”],[“offline1”,“offline2”]] )。您可以使用相应的索引号访问每个列表,如 printUserStatus(user_status) 中所示。 printUserStatus(user_status) 函数根据上面的示例将两个列表格式化为一个字符串,并返回结果。您需要使用逻辑填写 userIsOnline(名称) 功能,以检查您的用户是否在线/离线。 userIsOnline(name) 函数必须返回一个布尔值( True / False )才能生效。

有关用法示例,请参阅以下示例:

online  = []
offline = []
users   = ['bob', 'joe', 'frank', 'jimmy', 'louis']

def userIsOnline(name):
    # your status check logic here
    return True #or False

def getUserStatus(user_list):
    for name in user_list:
        if userIsOnline(name):
            online.append(name)
        else:
            offline.append(name)
    return [online, offline]

def printUserStatus(user_status):
    on  = ', '.join(user_status[0])
    off = ', '.join(user_status[1])
    return 'online: %s offline: %s' % (on, off)

# Example usage
status = getUserStatus(users)
print(printUserStatus(status))