Reputation: 261
I'm trying to create all possible stochiometries of chemical compounds, which essentially is combining strings/words: Let's say I have a list of elements:
els=['Ba','Ti','O']
and I say the number of each element can be maximally 3 and I want all possible combinations,with always each element at least once. The desired output would be:
['BaTiO','BaTiO2','BaTiO3','BaTi2O','BaTi2O2','BaTi2O3'.....]
AND the input list should be of arbitrary length, e.g. if it is
els=['Ba','Sr','Ti','O']
i want as a result:
['BaSrTiO','BaSrTiO2'....]
(the output could also be of the form [BaTiO,BaTiOO,BaTiOOO…] instead of the numbers)
I tried to come up with something using itertools, but I can't find a way how to do it.
Any suggestions?
Upvotes: 0
Views: 131
Reputation: 733
You could use itertools.permutations
for a shorter and maybe a bit more readable solution:
from itertools import permutations
elements = {"Ba", "Ti", "O"} # Set of elements
maxi = 3 # Maximum occurrence
raw_output = permutations(range(1, maxi + 1), len(elements))
for i in raw_output:
str_output = " ".join([f"{e}{v}" for e, v in zip(elements, i)])
print(str_output)
>>> O1 Ba2 Ti3
O1 Ba3 Ti2
O2 Ba1 Ti3
O2 Ba3 Ti1
O3 Ba1 Ti2
O3 Ba2 Ti1
Upvotes: 1
Reputation: 261
The solution was actually pretty easy in the end, just using "product" from itertools and the "pymatgen" library.
phase_space=['Ba','Ti','O']
maxi=5
list1=[]
for ii in range(len(phase_space)):
list1.append(list(range(1,1+maxi)))
new_list=list(product(*list1))
formulas=dict()
formula_list=[]
for ii in range(len(phase_space)):
formulas[phase_space[ii]]=1
for ii in range(len(new_list)):
for jj in range(len(phase_space)):
formulas[phase_space[jj]]=new_list[ii][jj]
comp = mg.Composition.from_dict(formulas)
if len(list(comp.as_dict().values()))>=2:
formula_list.append(comp.alphabetical_formula)
print(formula_list)
The output then is as desired:
['Ba1 O1 Ti1', 'Ba1 O2 Ti1', 'Ba1 O3 Ti1', 'Ba1 O4 Ti1', 'Ba1 O5 Ti1', 'Ba1 O1 Ti2', 'Ba1 O2 Ti2', 'Ba1 O3 Ti2', 'Ba1 O4 Ti2', 'Ba1 O5 Ti2', 'Ba1 O1 Ti3', 'Ba1 O2 Ti3', 'Ba1 O3 Ti3', 'Ba1 O4 Ti3', 'Ba1 O5 Ti3', 'Ba1 O1 Ti4', 'Ba1 O2 Ti4', 'Ba1 O3 Ti4', 'Ba1 O4 Ti4', 'Ba1 O5 Ti4', 'Ba1 O1 Ti5', 'Ba1 O2 Ti5', 'Ba1 O3 Ti5', 'Ba1 O4 Ti5', 'Ba1 O5 Ti5', 'Ba2 O1 Ti1', 'Ba2 O2 Ti1', 'Ba2 O3 Ti1', 'Ba2 O4 Ti1', 'Ba2 O5 Ti1', 'Ba2 O1 Ti2', 'Ba2 O2 Ti2', 'Ba2 O3 Ti2', 'Ba2 O4 Ti2', 'Ba2 O5 Ti2', 'Ba2 O1 Ti3', 'Ba2 O2 Ti3', 'Ba2 O3 Ti3', 'Ba2 O4 Ti3', 'Ba2 O5 Ti3', 'Ba2 O1 Ti4', 'Ba2 O2 Ti4', 'Ba2 O3 Ti4', 'Ba2 O4 Ti4', 'Ba2 O5 Ti4', 'Ba2 O1 Ti5', 'Ba2 O2 Ti5', 'Ba2 O3 Ti5', 'Ba2 O4 Ti5', 'Ba2 O5 Ti5', 'Ba3 O1 Ti1', 'Ba3 O2 Ti1', 'Ba3 O3 Ti1', 'Ba3 O4 Ti1', 'Ba3 O5 Ti1', 'Ba3 O1 Ti2', 'Ba3 O2 Ti2', 'Ba3 O3 Ti2', 'Ba3 O4 Ti2', 'Ba3 O5 Ti2', 'Ba3 O1 Ti3', 'Ba3 O2 Ti3', 'Ba3 O3 Ti3', 'Ba3 O4 Ti3', 'Ba3 O5 Ti3', 'Ba3 O1 Ti4', 'Ba3 O2 Ti4', 'Ba3 O3 Ti4', 'Ba3 O4 Ti4', 'Ba3 O5 Ti4', 'Ba3 O1 Ti5', 'Ba3 O2 Ti5', 'Ba3 O3 Ti5', 'Ba3 O4 Ti5', 'Ba3 O5 Ti5', 'Ba4 O1 Ti1', 'Ba4 O2 Ti1', 'Ba4 O3 Ti1', 'Ba4 O4 Ti1', 'Ba4 O5 Ti1', 'Ba4 O1 Ti2', 'Ba4 O2 Ti2', 'Ba4 O3 Ti2', 'Ba4 O4 Ti2', 'Ba4 O5 Ti2', 'Ba4 O1 Ti3', 'Ba4 O2 Ti3', 'Ba4 O3 Ti3', 'Ba4 O4 Ti3', 'Ba4 O5 Ti3', 'Ba4 O1 Ti4', 'Ba4 O2 Ti4', 'Ba4 O3 Ti4', 'Ba4 O4 Ti4', 'Ba4 O5 Ti4', 'Ba4 O1 Ti5', 'Ba4 O2 Ti5', 'Ba4 O3 Ti5', 'Ba4 O4 Ti5', 'Ba4 O5 Ti5', 'Ba5 O1 Ti1', 'Ba5 O2 Ti1', 'Ba5 O3 Ti1', 'Ba5 O4 Ti1', 'Ba5 O5 Ti1', 'Ba5 O1 Ti2', 'Ba5 O2 Ti2', 'Ba5 O3 Ti2', 'Ba5 O4 Ti2', 'Ba5 O5 Ti2', 'Ba5 O1 Ti3', 'Ba5 O2 Ti3', 'Ba5 O3 Ti3', 'Ba5 O4 Ti3', 'Ba5 O5 Ti3', 'Ba5 O1 Ti4', 'Ba5 O2 Ti4', 'Ba5 O3 Ti4', 'Ba5 O4 Ti4', 'Ba5 O5 Ti4', 'Ba5 O1 Ti5', 'Ba5 O2 Ti5', 'Ba5 O3 Ti5', 'Ba5 O4 Ti5', 'Ba5 O5 Ti5']
Upvotes: 0