1

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

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

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

如果您能告诉我一种有效的方法,将不胜感激。

4

6 回答 6

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)]
于 2013-07-20T23:11:55.450 回答
3

我会defaultdict(list)根据您的标准使用 a 并附加到它 - 这也将很好地扩展到忙碌/离开/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']

您可能还希望考虑使用 aset而不是列表来更快地查找/删除/插入名称,它还将阻止重复值的发生。

于 2013-07-20T23:15:07.517 回答
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)

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

于 2013-07-21T02:56:35.330 回答
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]
于 2013-07-21T02:54:00.380 回答
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])
于 2013-07-21T00:15:41.337 回答
0

这是我的尝试。

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

此示例构建了一个函数 ( getUserStatus(user_list) ),它返回主列表 ( [["online1", "online2"], ["offline1", "offline2"]] )中的两个列表 ( online/offline )。您可以使用相应的索引号访问每个列表,如printUserStatus(user_status)中所示。printUserStatus(user_status)函数根据上面的示例将两个列表格式化为字符串,并返回结果。您需要使用您的逻辑填写userIsOnline(name) 函数,以检查您的用户是否在线/离线。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))
于 2013-07-21T00:45:37.937 回答