我有一个列表列表:
Y= [[192, 193, 194, 195, 196, 197, 198, 199, 200],
[507, 508, 509],
[526, 527, 528, 529],
[560, 561],
[635, 636, 637]]
,我希望将每个列表的最后一个元素和第一个元素放入一个单独的列表中。 我使用了zip命令:
list(zip(*Y))[0]
所有第一个元素都给了我
[192,507,526,560,635]
但是当我使用list(zip(*Y))[-1]
我得到了[193, 508, 527, 561, 636]
代替[200,509,529,561,637]
我在做什么错了?
答案 0 :(得分:3)
您已经关闭-只需使用反向列表迭代器即可:
@SpringComponent
@UIScope
public class ContactEditor extends VerticalLayout {
private final ContactRepository repository;
private Contact contact;
TextField firstName = new TextField("First name");
TextField lastName = new TextField("Last name");
TextField phoneNumber = new TextField("Phone number");
TextField phoneType = new TextField( "Phone type");
Button save = new Button("Save", VaadinIcons.CHECK);
Button cancel = new Button("Cancel");
Button delete = new Button("Delete", VaadinIcons.TRASH);
CssLayout actions = new CssLayout(save, cancel, delete);
Binder<Contact> binder = new Binder<>(Contact.class);
@Autowired
public ContactEditor(ContactRepository repository, Contact contact) {
this.repository = repository;
this.contact = contact;
String type = contact.getPhoneType().getType();
addComponents(firstName, lastName, phoneNumber, phoneType, actions);
// bind using naming convention
**binder.bind(phoneType, contact.getPhoneType().getType(), contact.getPhoneType().setType(type));**
binder.bindInstanceFields(this);
// Configure and style components
setSpacing(true);
actions.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
save.setStyleName(ValoTheme.BUTTON_PRIMARY);
save.setClickShortcut(ShortcutAction.KeyCode.ENTER);
// wire action buttons to save, delete and reset
save.addClickListener(e -> repository.save(contact));
delete.addClickListener(e -> repository.delete(contact));
cancel.addClickListener(e -> editContact(contact));
setVisible(false);
}
public interface ChangeHandler {
void onChange();
}
public final void editContact(Contact c) {
if (c == null) {
setVisible(false);
return;
}
final boolean persisted = c.getId() != null;
if (persisted) {
// Find fresh entity for editing
contact = repository.findById(c.getId()).get();
}
else {
contact = c;
}
cancel.setVisible(persisted);
// Bind customer properties to similarly named fields
// Could also use annotation or "manual binding" or programmatically
// moving values from fields to entities before saving
binder.setBean(contact);
setVisible(true);
// A hack to ensure the whole form is visible
save.focus();
// Select all text in firstName field automatically
firstName.selectAll();
}
public void setChangeHandler(ChangeHandler h) {
// ChangeHandler is notified when either save or delete
// is clicked
save.addClickListener(e -> h.onChange());
delete.addClickListener(e -> h.onChange());
}
}
或更直接地,列表理解:
>>> list(zip(*[reversed(y) for y in Y]))[0]
(200, 509, 529, 561, 637)
答案 1 :(得分:2)
zip
压缩相同长度的可迭代对象。如果给出长度不同的可迭代对象,则它会在第一个长度的结尾处停止。
因此,由于最短列表的长度为2,因此您得到了第一个元素,然后是第二个元素……就是这样,所以[-1]
返回了第二个元素。
您可以使用itertools.zip_longest
,但这并没有真正的帮助,因为它通过在结尾处填充额外的None
值来处理不同长度的可迭代对象,而不是在中间插入额外的值。或将它们全部伸展到相同长度的东西。
最简单的方法是在压缩之前先获取每个 first 的开头和结尾:
Y= [[192, 193, 194, 195, 196, 197, 198, 199, 200],
[507, 508, 509],
[526, 527, 528, 529],
[560, 561],
[635, 636, 637]]
FL = [(sublist[0], sublist[-1]) for sublist in Y]
然后,您可以使用zip
将其移置:
F, L = zip(*FL)
或者只是zip
什么也没有,因为无论如何,移调并不会带来任何真正的好处,只是使事情变得更加复杂:
F = [sublist[0] for sublist in Y]
L = [sublist[-1] for sublist in Y]
或者,您可以压缩前后列表:
F = zip(*Y)
L = zip(*map(reversed, Y))
然后从每个元素中获取第一个元素:
f, l = next(F), next(L) # or list(F)[0] if you insist
我认为这与您尝试执行的操作最接近,但这似乎是最复杂的方法。