Вы можете использовать тот факт, что ваши списки являются просто 2-кортежами (технически списки длины 2) и использовать двоичный XOR ^
для 1, чтобы получить дополнительный элемент
lis_a, lis_b, lis_c = ['A', 'C'], ['T', 'G'], ['G', 'T']
states = []
for i, x in enumerate(lis_a):
for j, y in enumerate(lis_b):
for k, z in enumerate(lis_c):
state = (x, y, z)
complement = (lis_a[i^1], lis_b[j^1], lis_c[k^1])
print(state, complement)
states.append((state, complement))
# As a comprehension:
# states = [((x, y, z), (lis_a[i^1], lis_b[j^1], lis_c[k^1])) for i, x in enumerate(lis_a) for j, y in enumerate(lis_b) for k, z in enumerate(lis_c)]
Вывод:
('A', 'T', 'G') ('C', 'G', 'T')
('A', 'T', 'T') ('C', 'G', 'G')
('A', 'G', 'G') ('C', 'T', 'T')
('A', 'G', 'T') ('C', 'T', 'G')
('C', 'T', 'G') ('A', 'G', 'T')
('C', 'T', 'T') ('A', 'G', 'G')
('C', 'G', 'G') ('A', 'T', 'T')
('C', 'G', 'T') ('A', 'T', 'G')
Если вы хотите получить набор без повторяющихся перестановок (например, первая и последняя строка в выводе выше), вы можете использовать следующее:
lis_a, lis_b, lis_c = ['A', 'C'], ['T', 'G'], ['G', 'T']
states = []
for num in range(4):
k, j, i = num & 1, (num >> 1) & 1, (num >> 2) & 1 # 000, 001, 010, 011
state = lis_a[i], lis_b[j], lis_c[k]
compliment = lis_a[i ^ 1], lis_b[j ^ 1], lis_c[k ^ 1]
print(state, compliment)
states.append((state, compliment))
Выход:
('A', 'T', 'G') ('C', 'G', 'T')
('A', 'T', 'T') ('C', 'G', 'G')
('A', 'G', 'G') ('C', 'T', 'T')
('A', 'G', 'T') ('C', 'T', 'G')