# How to create all possible k-mers with a set of alphabets?

**URL:** https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186
**Category:** General Usage
**Tags:** question, iterators
**Created:** [June 22, 2022, 2:13pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186 "2022-06-22T14:13:09Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Bharat\_Ravi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bharat_ravi/32/28286_2.png) [@Bharat\_Ravi](https://discourse.julialang.org/u/Bharat_Ravi)
#### Post date: [June 22, 2022, 2:13pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/1 "2022-06-22T14:13:10Z")

</div>

I am trying to use `Iterators.product` to generate a list of all possible k-mers with a set of alphabets. Since I am a biologist, these letters happen to be the bases of DNA 😃 : “ATGC”

If I want to generate 3-mers then this works perfectly:

```julia
nucs = "ATGC"
join.(Iterators.product(nucs,nucs,nucs))
4×4×4 Array{String, 3}:
[:, :, 1] =
 "AAA" "ATA" "AGA" "ACA"
 "TAA" "TTA" "TGA" "TCA"
 "GAA" "GTA" "GGA" "GCA"
 "CAA" "CTA" "CGA" "CCA"

[:, :, 2] =
 "AAT" "ATT" "AGT" "ACT"
 "TAT" "TTT" "TGT" "TCT"
 "GAT" "GTT" "GGT" "GCT"
 "CAT" "CTT" "CGT" "CCT"

[:, :, 3] =
 "AAG" "ATG" "AGG" "ACG"
 "TAG" "TTG" "TGG" "TCG"
 "GAG" "GTG" "GGG" "GCG"
 "CAG" "CTG" "CGG" "CCG"

[:, :, 4] =
 "AAC" "ATC" "AGC" "ACC"
 "TAC" "TTC" "TGC" "TCC"
 "GAC" "GTC" "GGC" "GCC"
 "CAC" "CTC" "CGC" "CCC"

```

However, if I want to extend the same method for longer words, I have to keep repeating “nucs” as the arguments for `Iterators.product`. What I would like is a smart way where I specify the word size and I generate all possible words of that size. So far, I tried this:

```julia
join.(Iterators.product(Iterators.repeated(nucs,3)))
3-element Vector{String}:
 "ATGC"
 "ATGC"
 "ATGC"

```

I tried with `fill` too:

```julia
join.(Iterators.product(fill(nucs,1,3)))
join.(Iterators.product(fill(nucs,3)))

```

but I get the same output.

Using `collect(nucs)` instead of `nucs` also doesn’t give me the desired output

Any solutions?

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [June 22, 2022, 2:16pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/2 "2022-06-22T14:16:48Z")

</div>

Is

> **[GitHub - JuliaMath/Combinatorics.jl: A combinatorics library for Julia](https://github.com/JuliaMath/Combinatorics.jl)**
>
> A combinatorics library for Julia. Contribute to JuliaMath/Combinatorics.jl development by creating an account on GitHub.

what you are looking for?

Answer: No, OP is looking for solution below using Iterators.product with splatting.

---

<div class="post-metadata">

### Author: ![Bharat\_Ravi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bharat_ravi/32/28286_2.png) [@Bharat\_Ravi](https://discourse.julialang.org/u/Bharat_Ravi)
#### Post date: [June 22, 2022, 2:20pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/3 "2022-06-22T14:20:14Z")

</div>

I am looking for combinations of strings as I described. Thanks for the suggestion. Can you tell me which function I can use from this library to get what I want?

---

<div class="post-metadata">

### Author: ![Liozou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liozou/32/35118_2.png) [@Liozou](https://discourse.julialang.org/u/Liozou)
#### Post date: [June 22, 2022, 2:44pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/4 "2022-06-22T14:44:43Z")

</div>

```julia
join.(Iterators.product(Iterators.repeated(nucs,3)...))

```

may be what you are looking for. Notice the `...` compared to what you suggested: this is called [splatting](https://docs.julialang.org/en/v1.7/manual/faq/#...-splits-one-argument-into-many-different-arguments-in-function-calls).

Its performance can be problematic if you splat large iterators, but in this case the cost of calling `Iterators.product` will be much higher anyway so it shouldn’t matter. I would not advise replacing 3 with a number larger than 10 though, as you will probably need a few Gb to store the resulting array.

---

<div class="post-metadata">

### Author: ![Liozou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liozou/32/35118_2.png) [@Liozou](https://discourse.julialang.org/u/Liozou)
#### Post date: [June 22, 2022, 2:50pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/7 "2022-06-22T14:50:24Z")

</div>

That `Combinatorics` version is much more efficient than splatting 👍

---

<div class="post-metadata">

### Author: ![Bharat\_Ravi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bharat_ravi/32/28286_2.png) [@Bharat\_Ravi](https://discourse.julialang.org/u/Bharat_Ravi)
#### Post date: [June 22, 2022, 2:56pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/8 "2022-06-22T14:56:39Z")

</div>

This is great but I am not able to get longer strings. It returns `String[]`

---

<div class="post-metadata">

### Author: ![Liozou](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/liozou/32/35118_2.png) [@Liozou](https://discourse.julialang.org/u/Liozou)
#### Post date: [June 22, 2022, 3:12pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/9 "2022-06-22T15:12:52Z")

</div>

Ah right, it’s more efficient because it’s wrong 😅  
You are not looking for permutations of “ACGT” but for the cartesian product of this set of characters (you can check that the size of the two results do not match). I don’t know if there is something in `Combinatorics` that works… But the splatting version should yield the desired result.

---

<div class="post-metadata">

### Author: ![Bharat\_Ravi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bharat_ravi/32/28286_2.png) [@Bharat\_Ravi](https://discourse.julialang.org/u/Bharat_Ravi)
#### Post date: [June 22, 2022, 3:20pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/10 "2022-06-22T15:20:19Z")

</div>

Splatting works for me quite well (takes 3 seconds to produce all 10-mers). I just do this once so speed is not a big issue right now.

---

<div class="post-metadata">

### Author: ![AndiMD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andimd/32/6531_2.png) [@AndiMD](https://discourse.julialang.org/u/AndiMD)
#### Post date: [June 22, 2022, 3:25pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/11 "2022-06-22T15:25:55Z")

</div>

Another option, using Combinatorics:

```julia
using Combinatorics
with_replacement_combinations("ACGT",3) .|> x->multiset_permutations(x,3) .|> join

```

---

<div class="post-metadata">

### Author: ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)
#### Post date: [June 22, 2022, 4:12pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/12 "2022-06-22T16:12:08Z")

</div>

In this particular case, you can use the upcoming package Kmers.jl (not released yet, but close). There is no official “all kmers iterator”, but you can make one:

```julia
using Kmers

struct AllKmerIterator{A <: NucleicAcidAlphabet, K} end
Base.IteratorSize(::Type{<:AllKmerIterator}) = Base.HasLength()
function Base.length(::AllKmerIterator{A, K}) where {A, K}
    length(A())^K
end

function Base.iterate(it::AllKmerIterator{A, K}, state=0) where {A, K}
    state == length(it) && return nothing
    Kmers.kmertype(Kmer{A, K})((state % UInt64,)), state+1
end

```

This is much more efficient than the other suggestions, and yields `Kmer` objects, which are subtypes of `BioSequence`. For example:

```julia
julia> it = AllKmerIterator{DNAAlphabet{2}, 4}()
Main.AllKmerIterator{DNAAlphabet{2}, 4}()

julia> seq = first(it)
DNA 4-mer:
AAAA

julia> Kmers.reverse_complement(seq)
DNA 4-mer:
TTTT

```

My laptop iterates over all 10-mers using this code in about 2.5 miliseconds.  
Be aware that there will be rough edges since Kmers is in the alpha stage still.

Alternatively, BioSequences v2 contain a more primitive version of Kmers than Kmers.jl, but is well-tested and stable.

---

<div class="post-metadata">

### Author: ![cgeoga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cgeoga/32/216186_2.png) [@cgeoga](https://discourse.julialang.org/u/cgeoga)
#### Post date: [June 22, 2022, 4:32pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/13 "2022-06-22T16:32:57Z")

</div>

Do you need to use `join` and `String`s? If you used `collect` and `Symbols`, you’d end up with tuples instead of strings, but it’s the same information and much faster:

```julia
nucs_sym = (:A, :T, :G, :C)
nucs_str = ("A", "T", "G", "C")
@btime join.(Iterators.product(Iterators.repeated($nucs_str, 3)...)); # 4.773 \mu s, 258 alloc, 14.16 KiB
@btime collect(Iterators.product(Iterators.repeated($nucs_sym, 3)...)); # 97 ns, 1 alloc, 1.59 KiB

```

I don’t know what you’re doing and so maybe you need to convert to strings somehow in the end and this doesn’t help. Just thought I’d mention it because strings seem a bit wasteful here.

---

<div class="post-metadata">

### Author: ![Bharat\_Ravi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bharat_ravi/32/28286_2.png) [@Bharat\_Ravi](https://discourse.julialang.org/u/Bharat_Ravi)
#### Post date: [June 29, 2022, 1:28pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/14 "2022-06-29T13:28:26Z")

</div>

Thanks. Symbols are indeed fast but I am not able to create certain combinations that I can with strings. For example I need to create a set of sequences: (T/A/C) (CAT) (G/A/C). I should get 9 sequences.

If I am using strings, I can simply do this:

`join.(Iterators.product("TAC","C", "A","T" ,"GAC")`

How can I achieve the same using tuples of symbols?

---

<div class="post-metadata">

### Author: ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)
#### Post date: [June 29, 2022, 4:07pm UTC](https://discourse.julialang.org/t/how-to-create-all-possible-k-mers-with-a-set-of-alphabets/83186/15 "2022-06-29T16:07:03Z")

</div>

```julia
julia> for p in Iterators.product((:T,:A,:C), (:C,),(:A,),(:T,), (:G,:A,:C))
       @show p
       end
p = (:T, :C, :A, :T, :G)
p = (:A, :C, :A, :T, :G)
p = (:C, :C, :A, :T, :G)
p = (:T, :C, :A, :T, :A)
p = (:A, :C, :A, :T, :A)
p = (:C, :C, :A, :T, :A)
p = (:T, :C, :A, :T, :C)
p = (:A, :C, :A, :T, :C)
p = (:C, :C, :A, :T, :C)

```
