Julia Language
tuples
खोज…
वाक्य - विन्यास
- ए,
- ए, बी
- a, b = xs
- ()
- (ए,)
- (ए, बी)
- (ए, बी ...)
- टपल {टी, यू, वी}
- NTuple {N, T}
- टपल {टी, यू, वरग {वी}}
टिप्पणियों
ट्यूपल्स में दो कारणों से सरणियों की तुलना में बेहतर प्रदर्शन होता है: उनके प्रकार अधिक सटीक होते हैं, और उनकी अपरिवर्तनीयता उन्हें ढेर के बजाय ढेर पर आवंटित करने की अनुमति देती है। हालांकि, यह अधिक सटीक टाइपिंग दोनों अधिक संकलन-समय ओवरहेड और अधिक स्थिरता प्रकार को प्राप्त करने में कठिनाई के साथ आता है ।
टुपल्स का परिचय
Tuple
s एक ही प्रकार के या अलग-अलग प्रकारों के मनमाने ढंग से अलग-अलग वस्तुओं के संग्रहित क्रमबद्ध संग्रह हैं । आमतौर पर, टुपल्स का निर्माण (x, y)
सिंटैक्स का उपयोग करके किया जाता है।
julia> tup = (1, 1.0, "Hello, World!")
(1,1.0,"Hello, World!")
इंडेक्सिंग सिंटैक्स का उपयोग करके टुपल की अलग-अलग वस्तुओं को प्राप्त किया जा सकता है:
julia> tup[1]
1
julia> tup[2]
1.0
julia> tup[3]
"Hello, World!"
वे पुनरावृत्त इंटरफ़ेस लागू करते हैं, और इसलिए लूप के for
उपयोग करने पर इसे पुनरावृत्त किया जा सकता है :
julia> for item in tup
println(item)
end
1
1.0
Hello, World!
Tuples कई प्रकार के सामान्य संग्रह कार्यों का भी समर्थन करते हैं, जैसे कि reverse
या length
:
julia> reverse(tup)
("Hello, World!",1.0,1)
julia> length(tup)
3
इसके अलावा, tuples any
, all
, map
, या broadcast
सहित उच्च-क्रम के संग्रह कार्यों की एक किस्म का समर्थन broadcast
:
julia> map(typeof, tup)
(Int64,Float64,String)
julia> all(x -> x < 2, (1, 2, 3))
false
julia> all(x -> x < 4, (1, 2, 3))
true
julia> any(x -> x < 2, (1, 2, 3))
true
खाली टप्ले का उपयोग कर निर्माण किया जा सकता है ()
:
julia> ()
()
julia> isempty(ans)
true
हालांकि, एक तत्व के टपल का निर्माण करने के लिए, एक अनुगामी अल्पविराम की आवश्यकता होती है। इसका कारण यह है कोष्ठकों (है (
और )
) अन्यथा संचालन आपस में समूहित बजाय एक टपल के निर्माण के रूप में माना जाएगा।
julia> (1)
1
julia> (1,)
(1,)
स्थिरता के लिए, एक अनुगामी अल्पविराम को एक से अधिक तत्वों के साथ टुपल्स के लिए भी अनुमति दी जाती है।
julia> (1, 2, 3,)
(1,2,3)
टपल प्रकार
typeof
एक टपल की एक उप-प्रकार है Tuple
:
julia> typeof((1, 2, 3))
Tuple{Int64,Int64,Int64}
julia> typeof((1.0, :x, (1, 2)))
Tuple{Float64,Symbol,Tuple{Int64,Int64}}
अन्य डेटा प्रकारों के विपरीत, Tuple
प्रकार सहसंयोजक हैं । जूलिया में अन्य डेटा प्रकार आमतौर पर अपरिवर्तनीय हैं। इस प्रकार,
julia> Tuple{Int, Int} <: Tuple{Number, Number}
true
julia> Vector{Int} <: Vector{Number}
false
यह मामला है क्योंकि हर जगह एक Tuple{Number, Number}
को स्वीकार किया जाता है, इसलिए भी एक Tuple{Int, Int}
, क्योंकि इसमें भी दो तत्व हैं, जिनमें से दोनों संख्याएं हैं। एक Vector{Int}
बनाम Vector{Number}
के मामले में ऐसा नहीं है, Vector{Int}
स्वीकार करने वाले एक फ़ंक्शन के रूप में Vector{Number}
एक फ्लोटिंग पॉइंट (जैसे 1.0
) या एक जटिल संख्या (जैसे 1+3im
) को स्टोर करना चाह सकता है। एक वेक्टर
टपल प्रकार के सहसंयोजक का अर्थ है कि टपल Tuple{Number}
(फिर से Vector{Number}
विपरीत) वास्तव में एक सार है:
julia> isleaftype(Tuple{Number})
false
julia> isleaftype(Vector{Number})
true
Tuple{Number}
ठोस उपप्रकारों Tuple{Number}
में Tuple{Int}
, Tuple{Float64}
, Tuple{Rational{BigInt}}
, और आगे शामिल हैं।
Tuple
प्रकार में वस्तुओं की अनिश्चित संख्या को इंगित करने के लिए उनके अंतिम पैरामीटर के रूप में एक टर्मिनेटिंग Vararg
हो सकता है। उदाहरण के लिए, Tuple{Vararg{Int}}
सभी tuples का प्रकार है जिसमें Int
s, संभवतः शून्य:
julia> isa((), Tuple{Vararg{Int}})
true
julia> isa((1,), Tuple{Vararg{Int}})
true
julia> isa((1,2,3,4,5), Tuple{Vararg{Int}})
true
julia> isa((1.0,), Tuple{Vararg{Int}})
false
जबकि Tuple{String, Vararg{Int}}
एक स्ट्रिंग से मिलकर ट्यूपल को स्वीकार करता है, इसके बाद Int
का कोई भी नंबर (संभवतः शून्य) होता है।
julia> isa(("x", 1, 2), Tuple{String, Vararg{Int}})
true
julia> isa((1, 2), Tuple{String, Vararg{Int}})
false
सह-विचरण के साथ संयुक्त, इसका मतलब है कि Tuple{Vararg{Any}}
किसी भी टपल का वर्णन करता है। वास्तव में, Tuple{Vararg{Any}}
Tuple
कहने का एक और तरीका है:
julia> Tuple{Vararg{Any}} == Tuple
true
Vararg
एक दूसरे संख्यात्मक प्रकार के पैरामीटर को स्वीकार करता है जो बताता है कि इसके पहले प्रकार के पैरामीटर को कितनी बार होना चाहिए। (डिफ़ॉल्ट रूप से, यदि अनिर्दिष्ट है, तो यह दूसरा प्रकार का पैरामीटर एक प्रकार है जो किसी भी मूल्य को ले सकता है, यही वजह है कि ऊपर दिए गए Vararg
में किसी भी प्रकार के Int
को स्वीकार किया जाता है।) एक निर्दिष्ट Vararg
में समाप्त होने वाले Tuple
प्रकार स्वचालित रूप से विस्तारित हो जाएंगे। तत्वों की अनुरोधित संख्या:
julia> Tuple{String,Vararg{Int, 3}}
Tuple{String,Int64,Int64,Int64}
एक निर्दिष्ट Vararg
साथ समरूप ट्यूपल्स के लिए संकेतन मौजूद है: NTuple{N, T}
। इस अंकन में, N
टपल में तत्वों की संख्या को दर्शाता है, और T
स्वीकार किए गए प्रकार को दर्शाता है। उदाहरण के लिए,
julia> NTuple{3, Int}
Tuple{Int64,Int64,Int64}
julia> NTuple{10, Int}
NTuple{10,Int64}
julia> ans.types
svec(Int64,Int64,Int64,Int64,Int64,Int64,Int64,Int64,Int64,Int64)
ध्यान दें कि NTuple
रों एक निश्चित आकार से परे के रूप में बस में दिखाए जाते हैं NTuple{N, T}
का विस्तार करने के बजाय, Tuple
रूप है, लेकिन वे अभी भी एक ही प्रकार हैं:
julia> Tuple{Int,Int,Int,Int,Int,Int,Int,Int,Int,Int}
NTuple{10,Int64}
टपल प्रकारों पर प्रेषण
क्योंकि जूलिया फंक्शन पैरामीटर सूचियाँ स्वयं टुपल्स हैं, इसलिए विभिन्न प्रकार के टपल्स पर प्रेषण अक्सर विधि मापदंडों के माध्यम से स्वयं के लिए आसान होता है, अक्सर "स्प्लिटिंग" ...
ऑपरेटर के लिए उदार उपयोग के साथ। उदाहरण के लिए, Base
से टुपल्स के लिए reverse
के कार्यान्वयन पर विचार करें:
revargs() = ()
revargs(x, r...) = (revargs(r...)..., x)
reverse(t::Tuple) = revargs(t...)
इस तरह से टपल्स पर तरीकों को लागू करने से टाइप स्थिरता बनी रहती है , जो प्रदर्शन के लिए महत्वपूर्ण है। हम देख सकते हैं कि @code_warntype
मैक्रो का उपयोग करके इस दृष्टिकोण के लिए कोई ओवरहेड नहीं है:
julia> @code_warntype reverse((1, 2, 3))
Variables:
#self#::Base.#reverse
t::Tuple{Int64,Int64,Int64}
Body:
begin
SSAValue(1) = (Core.getfield)(t::Tuple{Int64,Int64,Int64},2)::Int64
SSAValue(2) = (Core.getfield)(t::Tuple{Int64,Int64,Int64},3)::Int64
return (Core.tuple)(SSAValue(2),SSAValue(1),(Core.getfield)(t::Tuple{Int64,Int64,Int64},1)::Int64)::Tuple{Int64,Int64,Int64}
end::Tuple{Int64,Int64,Int64}
यद्यपि पढ़ने में कुछ कठिन है, यहाँ कोड मूल मान के साथ तीसरे, 2 वें और 1 तत्वों के साथ क्रमशः नया टपल बना रहा है। कई मशीनों पर, यह बेहद कुशल LLVM कोड के लिए संकलित होता है, जिसमें लोड और स्टोर होते हैं।
julia> @code_llvm reverse((1, 2, 3))
define void @julia_reverse_71456([3 x i64]* noalias sret, [3 x i64]*) #0 {
top:
%2 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 1
%3 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 2
%4 = load i64, i64* %3, align 1
%5 = load i64, i64* %2, align 1
%6 = getelementptr inbounds [3 x i64], [3 x i64]* %1, i64 0, i64 0
%7 = load i64, i64* %6, align 1
%.sroa.0.0..sroa_idx = getelementptr inbounds [3 x i64], [3 x i64]* %0, i64 0, i64 0
store i64 %4, i64* %.sroa.0.0..sroa_idx, align 8
%.sroa.2.0..sroa_idx1 = getelementptr inbounds [3 x i64], [3 x i64]* %0, i64 0, i64 1
store i64 %5, i64* %.sroa.2.0..sroa_idx1, align 8
%.sroa.3.0..sroa_idx2 = getelementptr inbounds [3 x i64], [3 x i64]* %0, i64 0, i64 2
store i64 %7, i64* %.sroa.3.0..sroa_idx2, align 8
ret void
}
एकाधिक वापसी मान
ट्यूपल को अक्सर कई रिटर्न वैल्यू के लिए उपयोग किया जाता है। अधिकांश मानक पुस्तकालय, जिसमें पुनरावृत्त इंटरफ़ेस ( next
और done
) के दो कार्य शामिल हैं, दो संबंधित या अलग-अलग मान वाले टुपल्स लौटाते हैं।
ट्यूपल्स के आसपास के कोष्ठकों को कुछ स्थितियों में छोड़ा जा सकता है, जिससे कई वापसी मूल्यों को लागू करना आसान हो जाता है। उदाहरण के लिए, हम वास्तविक संख्या के धनात्मक और ऋणात्मक दोनों को वापस लेने के लिए एक फ़ंक्शन बना सकते हैं:
julia> pmsqrt(x::Real) = sqrt(x), -sqrt(x)
pmsqrt (generic function with 1 method)
julia> pmsqrt(4)
(2.0,-2.0)
विनाशकारी असाइनमेंट का उपयोग कई रिटर्न वैल्यूज़ को अनपैक करने के लिए किया जा सकता है। b
और जड़ों को वर्ग a
और b
में संग्रहीत करने के लिए, यह लिखने के लिए पर्याप्त है:
julia> a, b = pmsqrt(9.0)
(3.0,-3.0)
julia> a
3.0
julia> b
-3.0
इसका एक और उदाहरण है divrem
और fldmod
फ़ंक्शंस, जो एक पूर्णांक (क्रमशः divrem
या fldmod
) विभाजन और एक ही समय में शेष संचालन करते हैं:
julia> q, r = divrem(10, 3)
(3,1)
julia> q
3
julia> r
1