숫자
# Julia
i = 42 # 64비트 정수
f = 3.14 # 64비트 실수
c = 3.4 + 4.5im # 128비트 복소수
bi = BigInt(2)^1000 # 임의의 긴 정수
bf = BigFloat(1) / 7 # 임의의 정확도
r = 15//6 * 9//20 # 유리수
이에 상응하는 Python 코드:
# PYTHON
i = 42
f = 3.14
c = 3.4 + 4.5j
bi = 2**1000 # 정수는 긴 정수로 자동으로 바뀐다.
from decimal import Decimal
bf = Decimal(1) / 7
from fractions import Fraction
r = Fraction(15, 6) * Fraction(9, 20)
정수를 나누면 파이썬에서처럼 플로트가 나타납니다.
5 / 2 #2.5
정수 분할의 경우 ÷ 또는 div()를 사용합니다.
5 ÷ 2
div(5, 2)
% 연산자는 Python과 같은 모듈이 아닌 나머지 연산자입니다. 이는 음수에 대해서만 다릅니다.
Julia | Python |
3.4 + 4.5im | 3.4 + 4.5j |
BigInt(2)^1000 | 2**1000 |
BigFloat(3.14) | from decimal import Decimal Decimal(3.14) |
9//8 | from fractions import Fraction Fraction(9, 8) |
5/2 == 2.5 | 5/2 == 2.5 |
5÷2 == 2 or div(5, 2) |
5//2 == 2 |
57%10 == 7 | 57%10 == 7 |
(-57)%10 == -7 | (-57)%10 == 3 |
문자열
줄리아 문자열은 큰따옴표 " 또는 세개의 큰따옴표 """를 사용하지만, 작은따옴표 '는 사용하지 않습니다.
s = "ångström" # Julia 문자열은 기본적으로 UTF-8로 인코딩됩니다.
println(s) #"ångström"
s = "Julia strings
can span
several lines\n\n
and they support the \"usual\" escapes like
\x41, \u5bb6, and \U0001f60a!"
println(s)
#Julia strings
# can span
# several lines
#
#
# and they support the "usual" escapes like
# A, 家, and 😊!
문자열을 반복하려면 * 대신 repeat()을 사용하고 연결에는 + 대신 *를 사용합니다.
s = repeat("tick, ", 10) * "BOOM!"
println(s)
#tick, tick, tick, tick, tick, tick, tick, tick, tick, tick, BOOM!
동등한 Python 코드는 다음과 같습니다.
# PYTHON
s = "tick, " * 10 + "BOOM!"
print(s)
s.join(a) 대신 join(a, s) 사용:
s = join([i for i in 1:4], ", ")
println(s) #1, 2, 3, 4
마지막 조인에 대한 문자열을 지정할 수도 있습니다.
s = join([i for i in 1:4], ", ", " and ")
# "1, 2, 3 and 4"
split()은 생각했던 것 같이 작동한다.
split(" one three four ")
#3-element Vector{SubString{String}}:
# "one"
# "three"
# "four"
split("one,,three,four!", ",")
#4-element Vector{SubString{String}}:
# "one"
# ""
# "three"
# "four!"
추가사항
occursin("sip", "Mississippi") #문자열에서 sip찾기
#true
replace("I like coffee", "coffee" => "tea")
#"I like tea"
세개의 큰따옴표는 Python에서와 비슷하게 작동하지만, 들여쓰기를 제거하고 첫 줄 피드를 무시합니다.
s = """
1. the first line feed is ignored if it immediately follows \"""
2. triple quotes let you use "quotes" easily
3. indentation is ignored
- up to left-most character
- ignoring the first line (the one with \""")
4. the final line feed it n̲o̲t̲ ignored
"""
println("<start>")
println(s)
println("<end>")
#<start>
#1. the first line feed is ignored if it immediately follows """
#2. triple quotes let you use "quotes" easily
#3. indentation is ignored
# - up to left-most character
# - ignoring the first line (the one with """)
#4. the final line feed it n̲o̲t̲ ignored
#
#<end>
문자열 보간
문자열 보간은 $variable 및 $(식)을 사용한다.
total = 1 + 2 + 3
s = "1 + 2 + 3 = $total = $(1 + 2 + 3)"
println(s)
#1 + 2 + 3 = 6 = 6
\$는 달러 기호도 같이 출력해준다.
s = "The car costs \$10,000"
println(s)
#The car costs $10,000
원시 문자열
원시 문자열은 r"..." 대신 raw"..."를 사용합니다."
s = raw"In a raw string, you only need to escape quotes \", but not
$ or \. There is one exception, however: the backslash \
must be escaped if it's just before quotes like \\\"."
println(s)
#In a raw string, you only need to escape quotes ", but not
# $ or \. There is one exception, however: the backslash \
# must be escaped if it's just before quotes like \".
(원시 문자열에서는 따옴표 "만 이스케이프하면 되고 $ 또는 \는 이스케이프하면 안 됩니다. 그러나 한 가지 예외가 있습니다. \"와 같은 따옴표 바로 앞에 있는 경우 백슬래시 \를 이스케이프해야 합니다.)
s = raw"""
Triple quoted raw strings are possible too: $, \, \t, "
- They handle indentation and the first line feed like regular
triple quoted strings.
- You only need to escape triple quotes like \""", and the
backslash before quotes like \\".
"""
println(s)
#Triple quoted raw strings are possible too: $, \, \t, "
# - They handle indentation and the first line feed like regular
# triple quoted strings.
# - You only need to escape triple quotes like """, and the
# backslash before quotes like \".
(따옴표가 세 개인 원시 문자열도 가능합니다. : $, \, \t, "
- 들여쓰기 및 첫 번째 줄 피드는 일반 트리플 따옴표 문자열처럼 처리합니다.
- \"""와 같은 큰따옴표와 \\와 같은 따옴표 앞에 있는 백슬래시만 이스케이프하면 됩니다.)
문자
작은따옴표는 개별 유니코드 문자에 사용됩니다.
a = 'å' # Unicode code point (single quotes)
# å': Unicode U+00E5 (category Ll: Letter, lowercase)
더 정확히 말하면:
줄리아 "문자"는 단일 유니코드 코드 포인트(유니코드 스칼라라고도 함)를 나타냅니다.
하나의 그래픽, 즉 독자들이 하나의 문자로 인식할 수 있는 것을 생산하기 위해서는 여러 개의 코드 포인트가 필요할 수 있다. 이러한 일련의 코드 포인트를 "그래피 클러스터"라고 합니다.
예를 들어, 문자 é는 단일 코드 포인트 \u00E9 또는 그래피 클러스터 e + \u0301을 사용하여 나타낼 수 있습니다.
s = "café"
println(s, " has ", length(s), " code points")
#café has 4 code points
s = "cafe\u0301"
println(s, " has ", length(s), " code points")
#café has 5 code points
for c in "cafe\u0301"
display(c)
end
#'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
#'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
#'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)
#'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)
#'́': Unicode U+0301 (category Mn: Mark, nonspacing)
Julia는 32비트(4바이트)를 사용하는 'é'와 같은 개별 문자를 나타냅니다.
sizeof('é')
#4
그러나 문자열은 UTF-8 인코딩을 사용하여 표시됩니다. 이 인코딩에서 코드 포인트 0에서 127은 1바이트를 사용하여 표시되지만 127 이상의 코드 포인트는 2에서 6바이트를 사용하여 표시됩니다.
sizeof("a") #1
sizeof("é") #2
sizeof("家") #3
sizeof("🏳️🌈") #14 이것은 4개의 코드 포인트가 4 + 3 + 3 + 4 바이트인 그래프입니다.
[sizeof(string(c)) for c in "🏳️🌈"]
#4-element Vector{Int64}:
# 4
# 3
# 3
# 4
코드 포인트 대신 그래프를 통해 반복할 수 있습니다.
using Unicode
for g in graphemes("e\u0301🏳️🌈")
println(g)
end
#é
#🌈
문자열 인덱싱
문자열의 문자는 UTF-8 표현에서 시작 바이트의 위치를 기준으로 인덱싱됩니다. 예를 들어, 문자열 "être"의 문자 ê는 인덱스 1에 있지만, 문자 't'는 인덱스 3에 위치합니다. ê의 UTF-8 인코딩은 길이가 2바이트이기 때문입니다.
s = "être"
println(s[1])
println(s[3])
println(s[4])
println(s[5])
#ê
#t
#r
#e
인덱스 2에서 문자를 가져오려고 하면 예외가 발생합니다.
try
s[2]
catch ex
ex
end
#StringIndexError("être", 2)
한번 예외 처리 구문에 주목해보면(예외에 대해서는 나중에 설명함).
Julia | Python |
try ... catch ex ... end |
try ... except Exception as ex ... end |
유효한 문자 색인을 사용하여 하위 문자열을 쉽게 가져올 수 있습니다.
s[1:3]
#"êt"
문자열을 통해 반복할 수 있으며 모든 코드 포인트가 반환됩니다.
for c in s
println(c)
end
#ê
#t
#r
#e
또는 유효한 문자 색인을 통해 반복할 수 있습니다.
for i in eachindex(s)
println(i, ": ", s[i])
end
#1: ê
#3: t
#4: r
#5: e
문자열을 UTF-8로 나타낼 경우의 이점:
모든 유니코드 문자가 지원됩니다.
UTF-8은 상당히 작습니다(최소한 라틴어 스크립트의 경우).
ASCII 문자는 ASCII와 똑같이 UTF-8을 인코딩하는 유니코드 코드 포인트 0~127에 해당하므로 ASCII 문자만 기대하는 C 라이브러리와 잘 작동합니다.
단점:
UTF-8은 문자당 가변 바이트 수를 사용하므로 인덱싱이 어려워집니다.
그러나, 언어가 문자열의 시작에서 s[5]번째 문자를 검색하여 이 값을 숨기려 한다면 for i in 1:length(s); s[i]; end의 i와 같은 코드는 예기치 않게 비효율적일 수 있습니다. 각 반복마다 문자열의 시작 부분부터 검색이 있기 때문에 O(n) 대신 O(n^2) 성능이 발생합니다.
findfirst(isequal('t'), "être") #3
findlast(isequal('p'), "Mississippi") #10
findnext(isequal('i'), "Mississippi", 2) #2
findnext(isequal('i'), "Mississippi", 2 + 1) #5
findprev(isequal('i'), "Mississippi", 5 - 1) #2
기타 유용한 문자열 함수: ncodeunits(str), codeunits(str, i), thisind(str, i), nextind(str, i, n=1), prevind(str, i, n=1)입니다.
정규식
Julia에서 정규식을 만들려면 r"..." 구문을 사용합니다.
regex = r"c[ao]ff?(?:é|ee)"
#r"c[ao]ff?(?:é|ee)"
r"..." 표현식은 구문 분석 시 전자가 평가되고 후자가 런타임에 평가된다는 점을 제외하고 Regex("...")와 같으므로 Regex를 동적으로 구성해야 하는 경우가 아니라면 r"..."를 선택해야 합니다.
occursin(regex, "A bit more coffee?")
#true
m = match(regex, "A bit more coffee?")
m.match
#"coffee"
m.offset
#12
m = match(regex, "A bit more tea?")
isnothing(m) && println("I suggest coffee instead")
#I suggest coffee instead
regex = r"(.*)#(.+)"
line = "f(1) # nice comment"
m = match(regex, line)
code, comment = m.captures
println("code: ", repr(code))
println("comment: ", repr(comment))
#code: "f(1) "
#comment: " nice comment"
m[2]
" nice comment"
m.offsets
#2-element Vector{Int64}:
# 1
# 7
m = match(r"(?<code>.+)#(?<comment>.+)", line)
m[:comment]
#" nice comment"
replace("Want more bread?", r"(?<verb>more|some)" => s"a little")
#"Want a little bread?"
replace("Want more bread?", r"(?<verb>more|less)" => s"\g<verb> and \g<verb>")
#"Want more and more bread?"
'프로그래밍 > julia' 카테고리의 다른 글
1. 줄리아와 파이썬 및 기초 설정 (0) | 2021.08.15 |
---|---|
Julia를 공부하는 이유 (0) | 2021.08.15 |