例如,我的列表是
worker_processes 1;
events {
multi_accept on;
worker_connections 65535;
}
http {
charset utf-8;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
log_not_found off;
types_hash_max_size 2048;
client_max_body_size 16M;
# MIME
include mime.types;
default_type application/octet-stream;
upstream apigateway {
server apigateway.api:58732;
}
server {
listen 8081;
# reverse proxy
location /configurator-api-gw/ {
proxy_pass http://apigateway/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
我想将两个元素的第一个和最后一个边界保存在连续的值中。所以我需要得到的是:
my_list = [1,2,3,4,5, 9,10,11,12,13,14, 20,21,22,23,24,25,26,27]
如何简单或有效地获得此结果?
答案 0 :(得分:2)
使用more_itertools.consecutive_groups
import more_itertools as mit
my_list = [1,2,3,4,5,9,10,11,12,13,14,15]
x = [list(group) for group in mit.consecutive_groups(my_list)]
oputput = []
for i in x:
temp = [i[0],i[1],i[-2],i[-1]]
output.extend(temp)
输出:
[1,2,4,5,9,10,14,15]
答案 1 :(得分:2)
仅使用标准的itertools
模块,您可以执行以下操作:
from itertools import count, groupby
def remove_middle_of_seq(lst):
out = []
index = count()
for _, sequence in groupby(lst, lambda value: value - next(index)):
seq = list(sequence)
out.extend([seq[0], seq[1], seq[-2], seq[-1]])
return out
my_list = [1,2,3,4,5, 9,10,11,12,13,14, 20,21,22,23,24,25,26,27]
print(remove_middle_of_seq(my_list))
# [1, 2, 4, 5, 9, 10, 13, 14, 20, 21, 26, 27]
在连续值的组中,值与其索引之间的差是恒定的,因此groupby
可以使用该差作为键来对它们进行分组。
答案 2 :(得分:2)
from operator import itemgetter
from itertools import groupby
my_list = [1,2,3,4,5,9,10,11,12,13,14,20,21,22,23,24,25,26,27]
output = []
for k, g in groupby(enumerate(my_list), lambda x: x[0]-x[1]):
lst = list(map(itemgetter(1), g))
output.extend([lst[0], lst[1], lst[-2], lst[-1]])
print(output)
# [1, 2, 4, 5, 9, 10, 13, 14, 20, 21, 26, 27]
答案 3 :(得分:2)
在标准库中,实际上没有一个函数可以执行此类操作,因此您必须手动编写大多数函数。首先将所有升序分组,然后删除每个分组的中间,这是最简单的:
#include <iostream>
#include <vector>
#include <string>
#include <variant>
int main(){
std::vector<std::variant<int, float, std::string>> temp;
temp.emplace_back(std::string("A"));
temp.emplace_back(10);
temp.emplace_back(3.14f);
for (const auto& var: temp) {
if(std::get_if<std::string>(&var)) {
if(std::get<std::string>(var) == "A") std::cout << "found string\n";
}
if(std::get_if<int>(&var)) {
if(std::get<int>(var) == 10) std::cout << "found int\n";
}
if(std::get_if<float>(&var)) {
if(std::get<float>(var) == 3.14f) std::cout << "found float\n";
}
}
}
import itertools
def group_consecutive(sequence):
"""
Aggregates consecutive integers into groups.
>>> group_consecutive([8, 9, 1, 3, 4, 5])
[[8, 9], [1], [3, 4, 5]]
"""
result = []
prev_num = None
for num in sequence:
if prev_num is None or num != prev_num + 1:
group = [num]
result.append(group)
else:
group.append(num)
prev_num = num
return result
def drop_consecutive(sequence, keep_left=2, keep_right=2):
"""
Groups consecutive integers and then keeps only the 2 first and last numbers
in each group. The result is then flattened.
>>> drop_consecutive([1, 2, 3, 4, 5, 8, 9])
[1, 2, 4, 5, 8, 9]
"""
grouped_seq = group_consecutive(sequence)
for group in grouped_seq:
del group[keep_left:-keep_right]
return list(itertools.chain.from_iterable(grouped_seq))
另请参阅:
答案 4 :(得分:2)
您可以通过将列表自身以1的偏移量进行压缩来对相邻列表项进行配对,但用非连续值填充已移动的列表,以便您可以遍历配对并确定是否存在单独的组一对的差异不是1:
def consecutive_groups(l):
o = []
for a, b in zip([l[0] - 2] + l, l):
if b - a != 1:
o.append([])
o[-1].append(b)
return [s[:2] + s[-2:] for s in o]
给出示例输入,consecutive_groups(my_list)
返回:
[[1, 2, 4, 5], [9, 10, 13, 14], [20, 21, 26, 27]]