div.ProseMirror

Useful Python Snippets in Julia

This was inspired by reading Mikhail Raevskiy's story on his Top 29 Useful Python Snippets. I thought as a useful exercise is testing the expressiveness and ease of use of the Julia programming language, I would try to reimplement some of these examples in Julia.

Checking for uniqueness

Given an array can we figure out if this array has duplicates? Here is the original Python code.

def all_unique(lst):
    return len(lst) == len(set(lst))
x = [1,1,2,2,3,2,3,4,5,6]
y = [1,2,3,4,5]
all_unique(x), all_unique(y)
0.2s
Python
(False, True)

We can use an identical approach in Julia. It could be tempting to use Julia's unique function, but because it attempts to preserve element order it would be slower.

all_unique(xs) = length(xs) == length(Set(x))
x = [1,1,2,2,3,2,3,4,5,6]
y = [1,2,3,4,5]
all_unique(x), all_unique(y)
0.5s
(false, false)

Anagram

If you can rearrange the letters of a word to be equal to another word by using all the letters exactly once then you have an anagram. This is the kind of thing done various spelling or word games.

The original Python solution uses the Counter type to create basically a dictionary over how many times each letter occurs in the word. It could be tempting to use a Set here but that would fail as we need to take into account that some letters may occur multiple times.

from collections import Counter
def anagram(first, second):
    return Counter(first) == Counter(second)
anagram("abcd3", "3acdb")
0.2s
Python
True

Frankly I don't know why this solution was picked, as using sort seems like a simpler solution to me. The only complicating factor here is that Julia strings are UTF-8 encoded. Hence you cannot know ahead of time whether there is a character at say index 8, despite length(s) ≥ 8. Thus we must use collect to turn each string into an array of characters.

anagram(first, second) = sort(collect(first)) == sort(collect(second))
anagram("abcd3", "3acdb")
0.6s
true

Size in bytes

Find how many byes a string is made up of if we stored it in UTF-8 format on a file. Python strings are not natively encoded in UTF-8 so we would have to convert them to UTF-8 format to figure this out.

def byte_size(string):
    return(len(string.encode('utf-8')))
    
byte_size('?'), byte_size('Hello World'), byte_size("ÆØÅ")
0.1s
Python
(1, 11, 6)

Solving this problem in Julia feels a bit like cheating as Julia strings are already UTF-8, and hence there is already a built in function for giving the number of bytes.

sizeof('?'), sizeof("Hello World"), sizeof("ÆØÅ")
0.8s
(4, 11, 6)

Print the string N times

This is to print a string N times without needing to use a loop. The original Python version was written kind of like this:

n = 2
s = "Hello "
print(s * n)
0.4s
Python

We got a number of options we can use in Julia to accomplish this depending on what one will label as using a loop.

n = 2
s = "Hello "
println(s^2)
using Base.Iterators: repeated
foreach(print, repeated("Hello ", 2))
0.5s

Makes the first letters of words large

Capitalizing a title in Julia is rather trivial.

titlecase("julia is awesome")
0.4s
"Julia Is Awesome"

Removing false values

This comparison is a bit difficult to make since it is quite Python specific. In Python a lot of of different types of objects are considered false. Julia is more strongly typed and will not consider false something which is not of type Bool.

def compact(lst):
    return list(filter(bool, lst))
  
compact([0, 1, False, 2, '', 3, 'a', 's', 34])
0.2s
Python
[1, 2, 3, 'a', 's', 34]

But let us see if we can whip up some kind of similar versions.

xs = [0, 1, false, 2, "", 3, "a", "s", 34]
0.9s
9-element Array{Any,1}: 0 1 false 2 "" 3 "a" "s" 34

This is a bit of work in progress. A lot of these examples seem a bit too simple to be worth writing out. Should probably come up with some better examples for demonstrate Julia expressiveness.

Runtimes (2)