프로그래밍/julia

2. 숫자, 문자열,

luke12 2021. 8. 15. 12:39

숫자

# 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