Однолинейное решение:
mylist = [{0: 'c', 1: 'd', 2: 'e', 3: 'f'}[i] for i in [0, 1, 2, 3] if i in (x, y, z)]
Или:
mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]
Давайте сделаем педантичный, потому что есть различия, которые могут действительно повлиять на поведение вашего кода. Из комментариев, сделанных к статье «Old New Thing» , взята большая часть из следующих соображений.
Иногда память, возвращаемая новым оператором, будет инициализирована, а иногда она не будет в зависимости от того, является ли тип, который вы новичок, представляет собой POD (простые старые данные) , или если это класс, который содержит элементы POD и использует созданный компилятором конструктор по умолчанию.
Предположим:
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
В компиляторе C ++ 98 должно произойти следующее:
new A
- неопределенное значение new A()
- zero-initialize new B
- конструктор по умолчанию (B :: m не инициализирован) new B()
- конструкция по умолчанию (B :: m неинициализирована ) new C
- конструкция по умолчанию (C :: m инициализируется нулем) new C()
- конструкция по умолчанию (C :: m инициализируется нулем) В компиляторе, совместимом с C ++ 03, все должен работать следующим образом:
new A
- неопределенное значение new A()
- значение-инициализация A, которая является нулевой инициализацией, поскольку это POD. new B
- default-initializes (оставляет B :: m uninitialized) new B()
- значение-инициализирует B, который нуль инициализирует все поля, поскольку его по умолчанию ctor генерируется компилятором в противоположность определяемый пользователем. new C
- по умолчанию инициализирует C, который вызывает значение по умолчанию ctor. new C()
- значение инициализирует C, который вызывает значение по умолчанию ctor. Итак, во всех версиях C ++ существует разница между new A
и new A()
, поскольку A является POD.
И есть разница в поведении между C ++ 98 и C ++ 03 для случая new B()
.
Это один из пыльных углов C ++, который может свести вас с ума. Когда вы строите объект, иногда вам нужны / нужны парнеры, иногда вы их абсолютно не можете, и иногда это не имеет значения.
Предполагая, что Test является классом с определенным конструктором, нет никакой разницы. Последняя форма немного облегчает работу конструктора Test, но об этом.
В общем случае мы инициализируем по умолчанию в первом случае и инициализацию значения во втором случае.
Например: в случае с int (тип POD):
int* test = new int
- у нас есть любая инициализация, а значение * test может быть любым. int* test = new int()
- * test будет иметь значение 0. следующее поведение зависит от ваш тип Test. У нас есть дефференциальные случаи: Test имеет конструктор defult, Test создал конструктор по умолчанию, Test содержит член POD, член не POD ...
Нет, они одинаковы. Но есть разница между:
Test t; // create a Test called t
и
Test t(); // declare a function called t which returns a Test
Это из-за базового правила C ++ (и C): если что-то может быть объявлением, то это объявление.
Редактирование: повторите инициализацию проблем, связанных с данными POD и не-POD, в то время как я согласен со всем, что было сказано, я хотел бы просто отметить, что эти проблемы применимы только в том случае, вещь, созданная new'd или иначе построенная, не имеет определяемого пользователем конструктора. Если есть такой конструктор, он будет использоваться. Для 99,99% разумно спроектированных классов будет такой конструктор, и поэтому проблемы могут быть проигнорированы.