在条件和索引基础上对列表中的元素进行分组。

huangapple go评论57阅读模式
英文:

Group element in list based on conditions and indexes

问题

我有一组由姓名和角色组成的列表。然而,列表之间没有真正的逻辑关系。

例如,我有这个列表:

l = ['john', 'owner', 'mark', 'manager', 'alex', 'steve', 'employee', 'manager']  # 最后一个角色不应分配给任何人

我想将每个人分配到列表中紧邻或最接近他的角色。

期望的输出应该类似于:

output = [['john', 'owner'], ['mark', 'manager'], ['alex', 'employee'], ['steve', 'employee']]

我的猜想是向列表元素添加索引,然后根据一组条件确定在列表中查找的元素附近的元素。

这是我的脚本的一部分:

parties_role = [(idx, item) for idx, item in enumerate(l)]
    for item in parties_role:
        if "owner" not in str(item[1]) and 'manager' not in str(item[1]) and 'employee' not in str(item[1]):
        name = str(item[1])

代码的其余部分应查看包含关键词ownermanageremployee的列表项,并根据索引为当前的name变量分配最接近的角色。

英文:

I have a set of lists composed of names and role. However, there is no real logic between how the list are organized.

For instance, I have this list :

l = ['john', 'owner', 'mark', 'manager', 'alex', 'steve', 'employee', 'manager'] #the last role shouldn't be assigned to anyone 

I want to assign each person the role that is located next to it in the list or the closest one from left to right.

The desired output should be something like :

output = [['john', 'owner'], ['mark', 'manager'], ['alex', 'employee'], ['steve', 'employee']]  

My guess was to add indexes to the list elements, and than check which element based on a set of condition was closest to the list element I was looking at.

This is part of my script :

parties_role = [(idx, item) for idx,item in enumerate(l)]
    for item in parties_role:
        if "owner" not in str(item[1]) and 'manager' not in str(item[1]) and 'employee' not in str(item[1]):
        name = str(item[1])

The rest of the code shoud look at the list items that contain the keywords owner, manager and employee and assign to the current name variable the closest role based on the index.

答案1

得分: 3

# 使用在反转输入上的简单循环,你可以为一个或多个名字分配紧随其后的角色:

roles = {'owner', 'manager', 'employee'}

result = []
role = None
for x in reversed(l):
if x in roles:
role = x
continue
result.append([x, role])

如果顺序很重要

result = result[::-1]

输出:

[['john', 'owner'],
['mark', 'manager'],
['alex', 'employee'],
['steve', 'employee'],
]


<details>
<summary>英文:</summary>

Using a simple loop on the reversed input, you can assign the role that is immediately after one or several names:

roles = {'owner', 'manager', 'employee'}

result = []
role = None
for x in reversed(l):
if x in roles:
role = x
continue
result.append([x, role])

if order is important

result = result[::-1]

Output:

[['john', 'owner'],
['mark', 'manager'],
['alex', 'employee'],
['steve', 'employee'],
]


</details>



# 答案2
**得分**: 1

让我们创建一个"roles"集合:

```python
roles = {'owner', 'manager', 'employee'}

现在,让我们使用 reduce。我们的累加器是一个包含两个列表的元组:最终结果列表和第二个列表是迄今为止读取的名称的"bucket"。当它遇到一个角色时,它将这些名称映射到该角色并将它们添加到结果列表中。

from functools import reduce
grouped = reduce(
    lambda acc, x:
        (acc[0] + [[y, x] for y in acc[1]], []) if x in roles else
        (acc[0], acc[1] + [x]),
    l,
    ([], [])
)
grouped[0]
[[ 'john', 'owner'], [ 'mark', 'manager'], [ 'alex', 'employee'], [ 'steve', 'employee']]
英文:

Let's create a set of "roles":

roles = {&#39;owner&#39;, &#39;manager&#39;, &#39;employee&#39;}

Now, let's use reduce. Our accumulator is a tuple with two lists: the final result and the second list is a "bucket" of names read thus far. When it encounters a role, it maps those names to that role and adds them to the result list.

&gt;&gt;&gt; from functools import reduce
&gt;&gt;&gt; grouped = reduce(
...   lambda acc, x: 
...     (acc[0] + [[y, x] for y in acc[1]], []) if x in roles else 
...     (acc[0], acc[1] + [x]), 
...   l, 
...   ([], [])
... )
&gt;&gt;&gt; grouped[0]
[[&#39;john&#39;, &#39;owner&#39;], [&#39;mark&#39;, &#39;manager&#39;], [&#39;alex&#39;, &#39;employee&#39;], [&#39;steve&#39;, &#39;employee&#39;]]

答案3

得分: 1

这段代码可以从一组已知的角色开始...你需要某种方法来区分名字和角色,所以我假设这是可能的。有了这个,你可以根据字符串是名字还是角色进行分组。这应该会给你交替的名字和角色组。然后进行zip和组装:

from itertools import groupby

roles = {'owner', 'manager', 'employee'}    
l = ['john', 'owner', 'mark', 'manager', 'alex', 'steve', 'employee', 'manager']

groups = (list(v) for _, v in groupby(l, key=lambda s: s in roles))
result = [[name, list(roles)[0]] for names, roles in zip(groups, groups) for name in names]

这将产生一个名为result的结果:

[['john', 'owner'],
 ['mark', 'manager'],
 ['alex', 'employee'],
 ['steve', 'employee']]

它假设原始列表以一个名字开始。

英文:

You could start with a set of known roles...you need some way to tell names from roles, so I assume this is possible. With that you can group by whether the string is a name or a role. This should give you alternating groups of names and roles. Then zip and assemble:

from itertools import groupby

roles = {&#39;owner&#39;, &#39;manager&#39;, &#39;employee&#39;}    
l = [&#39;john&#39;, &#39;owner&#39;, &#39;mark&#39;, &#39;manager&#39;, &#39;alex&#39;, &#39;steve&#39;, &#39;employee&#39;, &#39;manager&#39;]

groups = (list(v) for _, v in groupby(l, key=lambda s: s in roles))
result = [[name, roles[0]] for names, roles in zip(groups, groups) for name in names]

This produces a result of:

[[&#39;john&#39;, &#39;owner&#39;],
 [&#39;mark&#39;, &#39;manager&#39;],
 [&#39;alex&#39;, &#39;employee&#39;],
 [&#39;steve&#39;, &#39;employee&#39;]]

It makes the assumption that the original list starts with a name.

答案4

得分: 1

  • 定义哪些字符串是角色,哪些不是(例如,创建一个有效roles的集合,假设其他一切都是名称)。
  • 迭代l中的每个name,使用enumerate来跟踪索引。
    • 对于每个name,找到l中下一个(在名称索引之后)是角色的元素。
&gt;&gt;&gt; l = ['john', 'owner', 'mark', 'manager', 'alex', 'steve', 'employee', 'manager']
&gt;&gt;&gt; roles = {'owner', 'manager', 'employee'}
&gt;&gt;&gt; [[name, next(e for e in l[i:] if e in roles)] for i, name in enumerate(l) if name not in roles]
[['john', 'owner'], ['mark', 'manager'], ['alex', 'employee'], ['steve', 'employee']]
英文:

I might do it like this:

  • Define which strings are roles and which aren't (e.g. create a set of valid roles, assume everything else is a name).
  • Iterate over each name in l, using enumerate to track the index.
    • For each name, find the next element in l (after the name's index) that's a role.
&gt;&gt;&gt; l = [&#39;john&#39;, &#39;owner&#39;, &#39;mark&#39;, &#39;manager&#39;, &#39;alex&#39;, &#39;steve&#39;, &#39;employee&#39;, &#39;manager&#39;]
&gt;&gt;&gt; roles = {&#39;owner&#39;, &#39;manager&#39;, &#39;employee&#39;}
&gt;&gt;&gt; [[name, next(e for e in l[i:] if e in roles)] for i, name in enumerate(l) if name not in roles]
[[&#39;john&#39;, &#39;owner&#39;], [&#39;mark&#39;, &#39;manager&#39;], [&#39;alex&#39;, &#39;employee&#39;], [&#39;steve&#39;, &#39;employee&#39;]]

huangapple
  • 本文由 发表于 2023年5月28日 03:00:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76348553.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定